Java进阶知识22 Spring的AOP编程

1、概述           

Aop:(Aspect Oriented Programming)面向切面编程
          功能: 让关注点代码与业务代码分离!

关注点:重复代码就叫做关注点;
切面: 关注点形成的类,就叫切面(类)!
            面向切面编程,就是指对很多功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。
切入点:执行目标对象方法,动态植入切面代码。
               可以通过切入点表达式,指定拦截哪些类的哪些方法;给指定的类在运行的时候植入切面类代码。

2、XML方式实现AOP编程  

2.1、我用到的jar包

    

这些Spring包  不一定每个都使用到

2.2、简单实例演示1(需要实现接口,相当于动态代理)Spring的动态代理:https://www.cnblogs.com/dshore123/p/11753623.html

IUserDao 接口类

1 package com.shore.dao;
2 
3 /**
4  * @author DSHORE/2019-11-7
5  *
6  */
7 public interface IUserDao {
8     public void save();
9 }

UserDao 接口的实现类

 1 package com.shore.dao.impl;
 2 
 3 import com.shore.dao.IUserDao;
 4 
 5 /**
 6  * @author DSHORE/2019-11-7
 7  *
 8  */
 9 public class UserDao implements IUserDao {
10 
11     @Override
12     public void save() { //3、执行业务方法
13         System.out.println("3、保存用户成功!");
14     }
15 }

Aop 类(程序执行到某一业务时,先去执行指定逻辑代码)

 1 package com.shore.aop;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 
 5 /**
 6  * @author DSHORE/2019-11-7
 7  *
 8  */
 9 public class Aop {
10     //around:环绕; ProceedingJoinPoint:必须添加(执行)
11     @SuppressWarnings("unused")
12     private void around(ProceedingJoinPoint pjp) throws Throwable {
13         System.out.println("2、环绕前....");
14         pjp.proceed();  // 执行目标方法(业务代码)
15         System.out.println("5、环绕后....");
16     }
17     
18     public void begin() {
19         System.out.println("1、开启事务......");
20     }
21     
22     public void commit() {
23         System.out.println("6、提交事务......");
24     }
25     
26     public void afterReturning() {
27         System.out.println("4、afterReturning(),返回消息");
28     }
29     
30     //有异常,执行这个第四步;没有异常,则执行上面的第四步
31     public void afterThrowing(){
32         System.out.println("4、afterThrowing(),返回异常消息");
33     }
34 }

Spring 配置文件(beans.xml)     切入点表达式:https://www.cnblogs.com/dshore123/p/11823849.html

 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 xmlns:aop
="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd"> 13 14 <!-- dao类 --> 15 <bean id="userDao" class="com.shore.dao.impl.UserDao"></bean> 16 <!-- 注入切面类 --> 17 <bean id="aop" class="com.shore.aop.Aop"></bean> 18 19 <aop:config> 20 <!-- 配置切入点 --> 21 <aop:pointcut expression="execution(* com.shore.dao.impl.*.*(..))" id="pt" /> 22 <!-- 配置切面(切入点形成的类,切入点就是重复的代码/方法) --> 23 <aop:aspect ref="aop"> 24 <!-- 1、开启事务。。。。。。 --> 25 <aop:before method="begin" pointcut-ref="pt" /> 26 <!-- 6、提交事务 --> 27 <aop:after method="commit" pointcut-ref="pt" /> 28 <!-- 环绕2/5 --> 29 <aop:around method="around" pointcut-ref="pt" /> 30 <!-- 4、afterReturning --> 31 <aop:after-returning method="afterReturning" 32 pointcut-ref="pt" /> 33 <!-- 4、异常(程序出现异常,执行这个第四步;没有异常,则执行上面的第四步) --> 34 <aop:after-throwing method="afterThrowing" 35 pointcut-ref="pt" /> 36 </aop:aspect> 37 </aop:config> 38 </beans>

测试类

 1 package com.shore.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.shore.dao.IUserDao;
 8 
 9 /**
10  * @author DSHORE/2019-11-7
11  *
12  */
13 public class MyTest {
14     @Test
15     public void testUserDao() {
16         ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
17         IUserDao userDao = (IUserDao) context.getBean("userDao");
18         //$Proxy4 :class com.sun.proxy.$Proxy4
19         System.out.println("这个相当于动态代理$Proxy4:"+userDao); //返回值:com.shore.dao.impl.UserDao@73aecc3a
20         userDao.save();
21     }
22 }

测试结果图

2.3、简单实例演示2(不需要实现接口,相当于Cglib子类代理) Spring的Cglib子类代理:https://www.cnblogs.com/dshore123/p/11753623.html

MessageDao 类(没有实现接口)

 1 package com.shore.dao.impl;
 2 
 3 /**
 4  * @author DSHORE/2019-11-7
 5  *
 6  */
 7 public class MessageDao {
 8     public void save() { //3、执行业务方法
 9         System.out.println("3、保存信息成功!");
10     }
11 }

Aop 类(和上面2.2中的一样,不变)

 1 package com.shore.aop;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 
 5 /**
 6  * @author DSHORE/2019-11-7
 7  *
 8  */
 9 public class Aop {
10     //around:环绕; ProceedingJoinPoint:必须添加(执行)
11     @SuppressWarnings("unused")
12     private void around(ProceedingJoinPoint pjp) throws Throwable {
13         System.out.println("2、环绕前....");
14         pjp.proceed();  // 执行目标方法(业务代码)
15         System.out.println("5、环绕后....");
16     }
17     
18     public void begin() {
19         System.out.println("1、开启事务......");
20     }
21     
22     public void commit() {
23         System.out.println("6、提交事务......");
24     }
25     
26     public void afterReturning() {
27         System.out.println("4、afterReturning(),返回消息");
28     }
29     
30     //有异常,执行这个第四步;没有异常,则执行上面的第四步
31     public void afterThrowing(){
32         System.out.println("4、afterThrowing(),返回异常消息");
33     }
34 }

Spring 配置文件(beans.xml)

 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 xmlns:aop
="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx.xsd 11 http://www.springframework.org/schema/aop 12 http://www.springframework.org/schema/aop/spring-aop.xsd"> 13 14 <!-- dao类 --> 15 <!-- <bean id="userDao" class="com.shore.dao.impl.UserDao"></bean> --> 16 <bean id="messageDao" class="com.shore.dao.impl.MessageDao"></bean> 17 <!-- 注入切面类 --> 18 <bean id="aop" class="com.shore.aop.Aop"></bean> 19 20 <aop:config> 21 <!-- 配置切入点 --> 22 <aop:pointcut expression="execution(* com.shore.dao.impl.*.*(..))" id="pt" /> 23 <!-- 配置切面(切入点形成的类,切入点就是重复的代码/方法) --> 24 <aop:aspect ref="aop"> 25 <!-- 1、开启事务。。。。。。 --> 26 <aop:before method="begin" pointcut-ref="pt" /> 27 <!-- 6、提交事务 --> 28 <aop:after method="commit" pointcut-ref="pt" /> 29 <!-- 环绕2/5 --> 30 <aop:around method="around" pointcut-ref="pt" /> 31 <!-- 4、afterReturning --> 32 <aop:after-returning method="afterReturning" 33 pointcut-ref="pt" /> 34 <!-- 4、异常(程序出现异常,执行这个第四步;没有异常,则执行上面的第四步) --> 35 <aop:after-throwing method="afterThrowing" 36 pointcut-ref="pt" /> 37 </aop:aspect> 38 </aop:config> 39 </beans>

测试类

1 @Test
2 public void testMessageDao() {
3     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
4     MessageDao messageDao = (MessageDao) context.getBean("messageDao");
5     System.out.println("这个相当于Cglib子类代理:"+messageDao);//返回值:com.shore.dao.impl.MessageDao@15412e75
6     messageDao.save();
7 }

测试结果图

原创作者:DSHORE

作者主页:http://www.cnblogs.com/dshore123/

原文出自:https://www.cnblogs.com/dshore123/p/11813822.html

欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

原文地址:https://www.cnblogs.com/dshore123/p/11813822.html