第七章:AOP技术
前言:
AOP技术是根据动态代理设计模式进行的技术。动态代理技术分jdk动态代理和cglib动态代理
jdk动态代理特点:
(1)继承java.lang.reflect.proxy类
(2)实现了真实类实现的接口
(3)真实类和代理类之间的关系是:他们都实现了相同的接口
cglib动态代理特点:
特点:
(1)代理类是真实类的子类
注:本片文章主要理解AOP编程,至于动态代理技术不做过多介绍,有需要的话,可以留言,下篇文章可以进行讲解。
7.1:AOP原理概述
AOP:Aspect Oriented Programming,面向切面编程
传统形式,web项目执行流程:
缺点:
(1)Bad Smell现象,指一些代码逻辑出现了在了不合适的层次。
例如:在service层有数据库的事务处理代码,不合乎规范
改进:
AOP编程:
本质上,属于动态代理设计模式
切面编程:类似于在链式程序指定流程中,在service层处进行截断,此处的断层成为切面,此处的service处的程序运行为竖向,可以看作service层的强化操作。
概念:
(1)Point(切点):表示要对哪个方法进行增强
(2)Advice(通知):表示额外增加的功能
(3)Aspect(切面):就是代理对象,(切面+切点)
(4)Weaving(织入):将通知添加到切点中的操作,生成动态代理的过程
7.2:AOP实现过程
7.2.1:导包
1. 日志包:
commons-logging.jar
2. Spring核心包:
spring-core.jar
spring-beans.jar
spring-context.jar
spring-expression.jar
3. aop依赖的jar包:
spring-aop.jar
aopalliance.jar -aop联盟提供的对aop的具体实现
7.2.2:测试用的service代码
spring支持两种动态代理的实现:
(1)如果提供了接口,就用jdk动态代理
(2)如果没有提供接口,就用cglib动态代理
7.2.3:提供通知
spring中的通知类型:
(1)前置通知:在切点方法调用前操作,MethodBeforeAdvice
(2)后置操作:在切点方法掉用后操作,AfterReturningAdvice
(3)异常通知:在切点方法执行发生异常时执行,ThrowsAdvice
(4)环绕通知:包含了前置通知、后置通知和异常通知,MethodInterceptor
public class DemoBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("我是前置通知...."); } }
7.2.4:配置AOP(织入/动态代理)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--配置service对象--> <bean id="userService" class="com.bjsxt.service.impl.UserServiceImpl" /> <bean id="testService" class="com.bjsxt.service.TestService" /> <!--配置通知对象--> <bean id="demoBefore" class="com.bjsxt.advice.DemoBeforeAdvice" /> <!--配置织入, 生成动态代理--> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!--配置目标对象--> <property name="targetName" value="userService" /> <!--配置通知--> <property name="interceptorNames"> <array> <value>demoBefore</value> </array> </property> </bean> <bean id="testProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetName" value="testService" /> <property name="interceptorNames"> <array> <value>demoBefore</value> </array> </property> </bean> </beans>
7.2.5:测试代码
public class TestAOP { @Test public void testAop2() { //cglib动态代理 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); TestService testProxy = context.getBean("testProxy", TestService.class); System.out.println(testProxy.getClass().getName()); System.out.println(testProxy.getClass().getSuperclass().getName()); testProxy.test(); } @Test public void testAop() { //jdk动态代理 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean("proxy", UserService.class); System.out.println(userService.getClass().getName()); userService.demo(); } }
来源:https://www.cnblogs.com/ncl-960301-success/p/10993192.html