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