Spring AOP 实现
来源:互联网 发布:有什么聊天软件 编辑:程序博客网 时间:2024/05/18 02:43
Spring AOP 实现
@(spring)[AOP]
spring aop的发展过程
- Spring AOP 实现
- 增强类型
- 前置增强
- schema方式实现
- 环绕增强
- 异常抛出增强
- 引介增强
- 前置增强
- 创建切面
- 静态方法匹配切面
- 自动代理
- 迎来新时代
- 注解实现AOP
- 增强类型
增强类型
spring 的aop底层是通过jdk动态代理和cglib动态代理技术为bean织入横切逻辑的。spring通过使用增强类定义横切逻辑。
Spring 提供了五种增强类型:
- 前置增强 : org.springframework.aop.MethodBeforeAdvice 是Spring目前可用的前置增强
- 后置增强 : org.springframework.aop.AfterReturningAdvice 目标方法后执行
- 环绕增强 : org.aopalliance.intercept.MethodInterceptor 目标方法前后执行
- 异常抛出增强 : org.springframework.aop.AfterReturningAdvice 抛出异常后执行
- 引介增强 : org.springframework.aop.support.DelegatingIntroductionInterceptor 为目标类增加新的方法和属性
前置增强
- 定义增强类
- 使用spring 的 ProxyFactory 将增强类目标类放入工厂,然后工厂实现代理
前置增强类:
public class BeforeAop implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("this is before advice..."); }}
ProxyFactory完成代理:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:spring.xml","classpath:spring-mvc.xml"})public class AopTest { @Test public void beforeAdvice(){ Waiter target = new NaviWaiter(); // 前置增强 BeforeAdvice beforeAdvice = new BeforeAop(); // spring代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); // JDK代理 proxyFactory.setInterfaces(target.getClass().getInterfaces()); proxyFactory.setTarget(target); proxyFactory.addAdvice(beforeAdvice); // 增强,设为true强制使用cglib代理(要引cglib库)// proxyFactory.setOptimize(true); Waiter waiter = (Waiter) proxyFactory.getProxy(); waiter.greetTo("miss"); }}
schema方式实现
spring的xml中配置bean
<bean class="com.lemontree.spring.aoptalk.BeforeAop" id="beforeAop"/><bean class="com.lemontree.spring.service.NaviWaiter" id="target"/><bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.lemontree.spring.service.Waiter" p:interceptorNames="beforeAop" p:target-ref="target"/>
测试:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:spring.xml","classpath:spring-mvc.xml"})public class AopTest { @Autowired private Waiter waiter; @Test public void schema(){ waiter.greetTo("tt"); }}
环绕增强
顾名思义
代码和和前置增强直接看代码
环绕增强
public class ArroundAop implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { Object[] o = invocation.getArguments(); String s = (String) o[0]; System.out.println("this is around..."+s); Object result = invocation.proceed(); System.out.println("this is ...."); return result; }}
异常抛出增强
ThrowsAdvice 并没有定义方法,他只是一个标识接口,spring会通过反射机制进行判断,但是必须以下面的方法签名进行定义:
void afterThrowing(Method method,Object[] args,Object target,Throwable);
方法名必须为afterThrowing,前三个参数可以选,要么都要要么都不要,最后一个是Throwable或它的子类
具体实现:
public class ThrowAop implements ThrowsAdvice { //定义增强逻辑 public void afterThrowing(Method method,Object[] args,Object target,Exception ex)throws Throwable{ System.out.println("方法名"+method.getName()); System.out.println("异常名称"+ex.getMessage()); System.out.println("回滚一波~~~~~"); }}
引介增强
引介增强比较特殊,他不是在目标方法中织入增强,而是为目标类创建新的方法和属性,所以增强的链接点是类级别的(上面的 增强是方法级别的)。
具体实现:
1. 定义一个接口:
public interface MoniterService { void wathchYou(boolean isWatch);}
- 定义引介增强
public class IntroductionAop extends DelegatingIntroductionInterceptor implements MoniterService{ private ThreadLocal<Boolean> moniMap = new ThreadLocal<>(); @Override public void wathchYou(boolean isWatch) { moniMap.set(isWatch); } @Override public Object invoke(MethodInvocation mi) throws Throwable { if (moniMap.get()!=null && moniMap.get()){ System.out.println("do it!"); } return super.invoke(mi); }}
- 测试
@Test public void introAop(){ Waiter target = new NaviWaiter(); // 引介增强 IntroductionInterceptor introductionAop = new IntroductionAop(); ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setInterfaces(target.getClass().getInterfaces()); proxyFactory.setTarget(target); proxyFactory.addAdvice(introductionAop); Waiter waiter = (Waiter) proxyFactory.getProxy(); waiter.greetTo("mss"); System.out.println("-----------------------"); MoniterService moniterService = (MoniterService) waiter; moniterService.wathchYou(true); waiter.greetTo("mss"); }
创建切面
增强类存在一个问题:增强被织入目标类的所有方法中。所以就需要Spring AOP去定位连接点。
所以创建切面的目的:找到连接点 ,为对应的方法织入横切逻辑
静态方法匹配切面
StaticMethodMatcherPointcutAdvisor 代表一个静态方法匹配切面,通过StaticMethodMatcherPointcut 定义切点
切面的创建:
1. 创建切面
2. 将增强类放入到切面中
3. 工厂生成代理类
具体实现:
切面:
public class StaticMethod extends StaticMethodMatcherPointcutAdvisor { @Override public boolean matches(Method method, Class<?> targetClass) { return "greetTo".equals(method.getName()); }}
测试:
@Test public void staticAdvisor() { Waiter target = new NaviWaiter(); // 前置增强 BeforeAop beforeAop = new BeforeAop(); // 静态普通方法名称匹配 StaticMethod staticMethod = new StaticMethod(); staticMethod.setAdvice(beforeAop); // 代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setInterfaces(target.getClass().getInterfaces()); proxyFactory.setTarget(target); proxyFactory.addAdvisor(staticMethod); //生成代理类 Waiter waiter = (Waiter) proxyFactory.getProxy(); waiter.greetTo("可以"); System.out.println("----------------"); waiter.serveTo("不可以?"); }
自动代理
先看看前面的schame
<bean class="com.lemontree.spring.aoptalk.BeforeAop" id="beforeAop"/> <bean class="com.lemontree.spring.service.NaviWaiter" id="target"/> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.lemontree.spring.service.Waiter" p:interceptorNames="beforeAop" p:target-ref="target"/>
可以看出,每次生成一个代理类都需要用ProxyFactoryBean配置一遍,十分麻烦。
所以spring提供了新的创建类:
- BeanNameAutoProxyCreator
- DefaultAdvisorAutoProxyCreator
还有很多中,这里只讲两个
有了Creator方法就可以嘿嘿嘿了
新的schame配置:
<bean class="com.lemontree.spring.aoptalk.BeforeAop" id="beforeAop"/> <bean class="com.lemontree.spring.service.NaviWaiter" id="waiter"/> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" p:interceptorNames="beforeAop" p:beanNames="*er" p:optimize="true"/>
迎来新时代
注解实现AOP
SpringInAction.4th.面向切面的Spring
- spring(AOP) 注解实现aop
- Spring的AOP实现
- spring AOP实现原理
- Spring Aop Schema 实现
- spring注解实现AOP
- Spring 实现AOP功能
- Spring 实现AOP
- spring实现AOP
- Spring Aop实现
- Spring AOP 实现原理
- Spring AOP的实现
- Spring中AOP实现
- Spring AOP 实现原理
- spring的aop实现
- Spring Aop 实现原理
- spring aop实现
- spring aop实现总结
- Spring AOP 实现原理
- JQuery警告:Duplicated jQuery selector
- 自定义View基础(一)——追根溯源,透过源码认识ViewRoot,DecorView和performTraversals方法
- Mac使用技巧-Mac OSX 使用rz、sz 远程上传、下载文件
- 我要开始在csdn胡扯了
- 浏览器在线浏览PDF文件之pdf.js
- Spring AOP 实现
- 第十二周 项目1-Prim 算法的验证
- 验证码乱码
- iOS-使用添加的花样字体
- WKWebView的缓存问题以及如何正确清理缓存
- thinkphp生成PDF文件
- Wannafly挑战赛2
- Spring Boot +swagger2
- 关于设置MFC应用程序窗口名称的方法