第一个版本

1)第一个版本:业务和切面紧耦合在一起,没有拆分.

  1. /**
  2. * 图书购买业务和事务切面耦合在一起
  3. */
  4. public class BookServiceImpl {
  5. public void buy(){
  6. try {
  7. System.out.println("事务开启.......");
  8. System.out.println("图书购买业务功能实现...........");
  9. System.out.println("事务提交.......");
  10. } catch (Exception e) {
  11. System.out.println("事务回滚.......");
  12. }
  13. }
  14. }

第二个版本

2)第二个版本:使用子类代理的方式拆分业务和切面.

  1. /**
  2. * 使用子类代理的方式进行图书业务和事务切面的拆分
  3. */
  4. public class BookServiceImpl {
  5. //在父类中只有干干净净的业务
  6. public void buy(){
  7. System.out.println("图书购买功能实现........");
  8. }
  9. }
  1. /**
  2. * 子类就是代理类,将父类的图书购买功能添加事务切面
  3. */
  4. public class SubBookServiceImpl extends BookServiceImpl {
  5. @Override
  6. public void buy() {
  7. try {
  8. //事务切面
  9. System.out.println("事务开启.........");
  10. //主业务实现
  11. super.buy();
  12. //事务切面
  13. System.out.println("事务提交.........");
  14. } catch (Exception e) {
  15. System.out.println("事务回滚.........");
  16. }
  17. }
  18. }
  1. public class MyTest02 {
  2. @Test
  3. public void test02(){
  4. BookServiceImpl service = new SubBookServiceImpl();
  5. service.buy();
  6. }
  7. }

第三个版本

3)第三个版本:使用静态代理拆分业务和切面.业务和业务接口已拆分.此时切面紧耦合在业务中.

  1. public interface Service {
  2. //规定业务功能
  3. void buy();
  4. }
  1. /**
  2. * 目标对象:业务功能的具体实现
  3. */
  4. public class BookServiceImpl implements Service {
  5. @Override
  6. public void buy() {
  7. System.out.println("图书购买业务功能实现............");
  8. }
  9. }
  1. public class ProductServiceImpl implements Service {
  2. @Override
  3. public void buy() {
  4. System.out.println("商品购买业务实现.........");
  5. }
  6. }
  1. /**
  2. * 静态代理已经实现了目标对象的灵活切换
  3. * 图书购买业务,商品购买业务
  4. */
  5. public class Agent implements Service {
  6. //设计成员变量的类型为接口,为了灵活切换目标对象
  7. public Service target;
  8. //使用构造方法传入目标对象
  9. public Agent(Service target){
  10. this.target = target;
  11. }
  12. @Override
  13. public void buy() {
  14. try {
  15. //切面功能
  16. System.out.println("事务开启......"); //日志 权限验证
  17. //业务功能
  18. target.buy();
  19. //切面功能
  20. System.out.println("事务提交.......");
  21. } catch (Exception e) {
  22. System.out.println("事务回滚.......");
  23. }
  24. }
  25. }
  1. public class MyTest03 {
  2. @Test
  3. public void test02(){
  4. Service agent = new Agent(new ProductServiceImpl());
  5. agent.buy();
  6. }
  7. }

第四个版本

4)第四个版本:使用静态代理拆分业务和业务接口,切面和切面接口.
image.png

  1. public interface Service {
  2. //规定业务功能
  3. void buy();
  4. }
  1. /**
  2. * 目标对象:业务功能的具体实现
  3. */
  4. public class BookServiceImpl implements Service {
  5. @Override
  6. public void buy() {
  7. System.out.println("图书购买业务功能实现............");
  8. }
  9. }
  1. public class ProductServiceImpl implements Service {
  2. @Override
  3. public void buy() {
  4. System.out.println("商品购买业务实现.........");
  5. }
  6. }
  1. public interface AOP {
  2. //该方法不用 必须实现,用到实现即可
  3. default void before(){}
  4. default void after(){}
  5. default void exception(){}
  6. }
  1. public class LogAop implements AOP {
  2. @Override
  3. public void before() {
  4. System.out.println("前置日志输出.......");
  5. }
  6. }
  1. public class TransAop implements AOP {
  2. @Override
  3. public void before() {
  4. System.out.println("事务开启........");
  5. }
  6. @Override
  7. public void after() {
  8. System.out.println("事务提交........");
  9. }
  10. @Override
  11. public void exception() {
  12. System.out.println("事务回滚........");
  13. }
  14. }
  1. public class Agent implements Service {
  2. //传入目标(业务)对象,切面对象
  3. Service target;
  4. AOP aop;
  5. //使用构造方法初始化业务对象和切面对象
  6. public Agent(Service target,AOP aop){
  7. this.target = target;
  8. this.aop = aop;
  9. }
  10. @Override
  11. public void buy() {
  12. try {
  13. //切面
  14. aop.before(); //事务 日志
  15. //业务
  16. target.buy(); //图书 商品
  17. //切面
  18. aop.after(); //事务
  19. } catch (Exception e) {
  20. //切面
  21. aop.exception();
  22. }
  23. }
  24. }
  1. public class MyTest04 {
  2. @Test
  3. public void test02(){
  4. Service agent = new Agent(new ProductServiceImpl(),new TransAop());
  5. //切入多个切面的功能
  6. Service agent1 = new Agent(agent,new LogAop());
  7. agent1.buy();
  8. }
  9. }

第五个版本

5)第五个版本:使用动态代理完成第四个版本的优化.
image.png

  1. public interface Service {
  2. //规定业务功能
  3. void buy();
  4. //增加有参有返回值的方法测试代理功能
  5. default String show(int age){return null;}
  6. }
  1. /**
  2. * 目标对象:业务功能的具体实现
  3. */
  4. public class BookServiceImpl implements Service {
  5. @Override
  6. public void buy() {
  7. System.out.println("图书购买业务功能实现............");
  8. }
  9. @Override
  10. public String show(int age) {
  11. System.out.println("这是show()方法被调用...."+age);
  12. return "abcd";
  13. }
  14. }
  1. public class ProductServiceImpl implements Service {
  2. @Override
  3. public void buy() {
  4. System.out.println("商品购买业务实现.........");
  5. }
  6. }
  1. public interface AOP {
  2. default void before(){}
  3. default void after(){}
  4. default void exception(){}
  5. }
  1. public class LogAop implements AOP {
  2. @Override
  3. public void before() {
  4. System.out.println("前置日志输出.......");
  5. }
  6. }
  1. public class TransAop implements AOP {
  2. @Override
  3. public void before() {
  4. System.out.println("事务开启........");
  5. }
  6. @Override
  7. public void after() {
  8. System.out.println("事务提交........");
  9. }
  10. @Override
  11. public void exception() {
  12. System.out.println("事务回滚........");
  13. }
  14. }
  1. public class ProxyFactory {
  2. public static Object getAgent(Service target,AOP aop){
  3. //返回生成的动态代理对象
  4. return Proxy.newProxyInstance(
  5. //类加载器
  6. target.getClass().getClassLoader(),
  7. //目标对象实现的所有的接口
  8. target.getClass().getInterfaces(),
  9. //代理功能实现
  10. new InvocationHandler() {
  11. @Override
  12. public Object invoke(
  13. //生成的代理对象
  14. Object proxy,
  15. //正在被调用的目标方法buy(),show()
  16. Method method,
  17. //目标方法的参数
  18. Object[] args) throws Throwable {
  19. Object obj = null;
  20. try {
  21. //切面
  22. aop.before(); //事务 日志
  23. //业务
  24. obj = method.invoke(target,args);
  25. //切面
  26. aop.after();
  27. } catch (Exception e) {
  28. //切面
  29. aop.exception();
  30. }
  31. return obj; //目标方法的返回值
  32. }
  33. }
  34. );
  35. }
  36. }
  1. public class MyTest05 {
  2. @Test
  3. public void test02(){
  4. //得到动态代理对象
  5. Service agent = (Service) ProxyFactory.getAgent(new BookServiceImpl(),new TransAop());
  6. agent.buy();
  7. }
  8. @Test
  9. public void test03(){
  10. //得到动态代理对象
  11. Service agent = (Service) ProxyFactory.getAgent(new BookServiceImpl(),new LogAop());
  12. System.out.println(agent.getClass());
  13. String s = agent.show(22);
  14. System.out.println(s);
  15. }
  16. }

Spring原生AOP代码实现(了解)

重要的是Aspect框架
image.png

  1. public interface BookService {
  2. public boolean buy(String userName,String bookName,double price);
  3. public void comment(String userName,String comments);
  4. }
  1. public class BookServiceImpl implements BookService {
  2. @Override
  3. public boolean buy(String userName, String bookName, double price) {
  4. System.out.println("购买图书功能实现...........");
  5. System.out.println(userName+"购买了"+bookName+",花费了"+price+"元.");
  6. System.out.println(userName+"增加了"+(price/10));
  7. System.out.println("图书购买业务结束");
  8. return false;
  9. }
  10. @Override
  11. public void comment(String userName, String comments) {
  12. System.out.println("评论功能的实现 ...........");
  13. System.out.println(userName+"发表了"+comments+".");
  14. System.out.println("评论功能结束 ...........");
  15. }
  16. }
  1. public class LogAdvice implements MethodBeforeAdvice {
  2. @Override
  3. public void before(Method method, Object[] objects, Object o) throws Throwable {
  4. SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
  5. System.out.println("\n[系统日志]"+sf.format(new Date())+"---"+method.getName()+ Arrays.toString(objects));
  6. }
  7. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <!--创建业务对象-->
  6. <bean id ="bookServiceTarget" class="com.bjpowernode.service.impl.BookServiceImpl"></bean>
  7. <!--创建切面的对象-->
  8. <bean id="logAdvice" class="com.bjpowernode.advice.LogAdvice"></bean>
  9. <!--绑定业务和切面-->
  10. <bean id="bookService" class="org.springframework.aop.framework.ProxyFactoryBean">
  11. <!--配置业务接口-->
  12. <property name="interfaces" value="com.bjpowernode.service.BookService"></property>
  13. <!--配置切面-->
  14. <property name="interceptorNames">
  15. <list>
  16. <value>logAdvice</value>
  17. </list>
  18. </property>
  19. <!--织入-->
  20. <property name="target" ref="bookServiceTarget"></property>
  21. </bean>
  22. </beans>
  1. public class MyTest {
  2. @Test
  3. public void test01(){
  4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. BookService proxy = (BookService) ac.getBean("bookService");
  6. System.out.println(proxy.getClass());
  7. proxy.buy("张三","平凡的世界",55);
  8. proxy.comment("张三","还是很好看,可以看一看.....");
  9. }
  10. }