AOP增强详解
2017-09-21 14:59
169 查看
增强是AOP的核心部分之一,它包含逻辑代码和方位,增强就是一重最简单的切面。
增强的类型:
前置增强
后置增强
环绕增强
异常抛出增强
引介增强
主要思想创建前置增强,使用代理。
ProxyFactory 是一个代理工厂,他的底层就是使用jdk动态代理或者CGlib动态代理,根据情况自动选择,也可以使用setOptimize(true)强制使用CGlib代理。
下面介绍一下spring中配置增强的方法:
通过spring配置的增强如何使用?见下面代码:
对于后置增强:其他使用方法和前置增强一样。下面我们看看如何定义后置增强,
环绕增强的定义方法:
异常增强的定义方法:
引介增强:它不是在目标方法周围织入增强,而是为目标类创建新的方法和属性,连接点就是类级别的。
自己不实现某一个接口,但是代理实现了。返回的是代理,具有某些特殊功能
它能干嘛呢?比如我们织入增强,需要手动控制增强的开启与关闭,这时就要使用引介增强了。
增强都是需要实现特定的接口,和方法、
然后通过代理,设置代理的接口,目标类,增强,底层代理方式。从而实现增强的织入,可是这种织入,是对目标类的所有方法而言的。如果我们只想对目标类的某一方法进行处理,我们该如何处理呢?这时候就要使用切面了。
增强+切点=切面。增强就是最简单的一种切面。
增强的类型:
前置增强
后置增强
环绕增强
异常抛出增强
引介增强
package com.smart.advice; public interface Waiter { //接口 void greetTo(String name); void serveTo(String name); }
package com.smart.advice; public class NaiveWaiter implements Waiter {//接口实现类(目标类) public void greetTo(String name) { System.out.println("greet to "+name+"..."); } public void serveTo(String name){ System.out.println("serving "+name+"..."); } }
package com.smart.advice; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; //增强类 public class GreetingBeforeAdvice implements MethodBeforeAdvice {//定义的一个接口,before是唯一的方法,par1 目标类的方法,par2 目标类的入参,par3 目标类 public void before(Method method, Object[] args, Object obj) throws Throwable { String clientName = (String)args[0]; System.out.println("How are you!Mr."+clientName+"."); } }
package com.smart.advice; import org.springframework.aop.BeforeAdvice; import org.springframework.aop.framework.ProxyFactory; import static org.testng.Assert.*; import org.testng.annotations.*; public class BeforeAdviceTest { @Test public void before() { Waiter target = new NaiveWaiter(); //目标类 BeforeAdvice advice = new GreetingBeforeAdvice();//增强类 ProxyFactory pf = new ProxyFactory(); //代理 pf.setInterfaces(target.getClass().getInterfaces());//指定代理的接口 pf.setOptimize(true);//指定底层处理方式为CGlib pf.setTarget(target);//指定目标类 pf.addAdvice(advice);//指定增强 Waiter proxy = (Waiter)pf.getProxy(); //获得代理 proxy.greetTo("John"); proxy.serveTo("Tom"); } }
主要思想创建前置增强,使用代理。
ProxyFactory 是一个代理工厂,他的底层就是使用jdk动态代理或者CGlib动态代理,根据情况自动选择,也可以使用setOptimize(true)强制使用CGlib代理。
下面介绍一下spring中配置增强的方法:
<bean id="greetingBefore" class="com.smart.advice.GreetingBeforeAdvice" /> <bean id="greetingAfter" class="com.smart.advice.GreetingAfterAdvice" /> <bean id="greetingAdvice" class="com.smart.advice.GreetingBeforeAdvice" /> <bean id="greetingAround" class="com.smart.advice.GreetingInterceptor" /> <bean id="target" class="com.smart.advice.NaiveWaiter" /> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.smart.advice.Waiter"//指定接口 p:target-ref="target"//指定目标类 p:interceptorNames="greetingAround【,greetingAfter】" />//指定增强,可以指定多个增强,标准格式为: // <property name = "interceptorNames"> // <list> // <idref local = "greetingBefore"/> // <idref local = "greetingAfter"/> // </list> // </property> // p:optimize = true;//指定底层实现方式
通过spring配置的增强如何使用?见下面代码:
@Test public void advice() { String configPath = "com/smart/advice/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);//获取资源 Waiter waiter = (Waiter)ctx.getBean("waiter");//获取bean,通过spring配置,该Bean以及被加强 waiter.greetTo("John"); }
对于后置增强:其他使用方法和前置增强一样。下面我们看看如何定义后置增强,
package com.smart.advice; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class Gree 4000 tingAfterAdvice implements AfterReturningAdvice {//实现指定接口,和指定方法即可 public void afterReturning(Object returnObj, Method method, Object[] args, Object obj) throws Throwable { System.out.println("Please enjoy yourself!"); } }
环绕增强的定义方法:
package com.smart.advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class GreetingInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { Object[] args = invocation.getArguments(); String clientName = (String)args[0]; System.out.println("How are you!Mr."+clientName+"."); Object obj = invocation.proceed(); System.out.println("Please enjoy yourself!"); return obj; } }
异常增强的定义方法:
package com.smart.advice; import java.lang.reflect.Method; import org.springframework.aop.ThrowsAdvice; public class TransactionManager implements ThrowsAdvice {//同样实现指定类,和指定方法 public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable { System.out.println("-----------"); System.out.println("method:" + method.getName()); System.out.println("抛出异常:" + ex.getMessage()); System.out.println("成功回滚事务。"); } }
引介增强:它不是在目标方法周围织入增强,而是为目标类创建新的方法和属性,连接点就是类级别的。
自己不实现某一个接口,但是代理实现了。返回的是代理,具有某些特殊功能
它能干嘛呢?比如我们织入增强,需要手动控制增强的开启与关闭,这时就要使用引介增强了。
package com.smart.introduce; import org.aopalliance.intercept.MethodInvocation; //引介增强提供的实现类,所以这里不是实现,而是继承 import org.springframework.aop.support.DelegatingIntroductionInterceptor; public class ControllablePerformaceMonitor extends DelegatingIntroductionInterceptor implements Monitorable, Testable { //线程局部变量,支持范型 private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>(); //属性注入 public void setMonitorActive(boolean active) { MonitorStatusMap.set(active); } public Object invoke(MethodInvocation mi) throws Throwable { Object obj = null; //获取线程局部变量,通过这个变量控制是否进行增强 if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) { PerformanceMonitor.begin(mi.getClass().getName() + "." + mi.getMethod().getName()); obj = super.invoke(mi); PerformanceMonitor.end(); } else { obj = super.invoke(mi); } return obj; } public void test() { // TODO Auto-generated method stub System.out.println("dd"); } }
<bean id="pmonitor" class="com.smart.introduce.ControllablePerformaceMonitor" /> <bean id="forumServiceTarget" class="com.smart.introduce.ForumService" /> <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean" //引介增强实现的接口 p:interfaces="com.smart.introduce.Monitorable" //目标类 p:target-ref="forumServiceTarget" //引介增强 p:interceptorNames="pmonitor" //引介增强必须使用CGlib动态代理,这里必须设置为true p:proxyTargetClass="true" />
@Test public void introduce(){ String configPath = "com/smart/introduce/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); ForumService forumService = (ForumService)ctx.getBean("forumService"); forumService.removeForum(10); forumService.removeTopic(1022); Monitorable moniterable = (Monitorable)forumService; moniterable.setMonitorActive(true); forumService.removeForum(10); forumService.removeTopic(1022); }
增强都是需要实现特定的接口,和方法、
然后通过代理,设置代理的接口,目标类,增强,底层代理方式。从而实现增强的织入,可是这种织入,是对目标类的所有方法而言的。如果我们只想对目标类的某一方法进行处理,我们该如何处理呢?这时候就要使用切面了。
增强+切点=切面。增强就是最简单的一种切面。
相关文章推荐
- spring AOP详解之--前置增强 (MethodBeforeAdvice)
- Spring 之AOP AspectJ切入点语法详解(最全了,不需要再去其他地找了)
- Spring AOP——java的动态代理机制详解
- Spring AOP三种拦截方式举例详解
- aop面向切面详解
- 字节码增强和AOP
- spring AOP 环绕增强小Demo
- Spring AOP详解
- Android AOP注解Annotation详解(一)
- 深入浅出Spring(二) AOP详解
- Spring IoC AOP详解
- Spring AOP详解
- 详解webpack之图片引入-增强的file-loader:url-loader
- AOP详解
- 开源框架spring详解-----AOP的深刻理解
- 利用Spring AOP自定义注解解决日志和签名校验 详解
- Oracle 11g R1中数据泵增强详解
- Spring之AOP详解
- Spring详解(五)------AspectJ 实现AOP
- 开源框架spring详解-----AOP的深刻理解(1)