AOP是Aspect Oriented Programing的简称,译为面向切面编程。
AOP通过横向抽取机制为无法通过纵向继承体系进行抽象的重复新代码提供了解决方案。AOP将分散在各个业务逻辑代码中的相同代码通过横向切割的方式抽取到一个独立的模块中,去除和业务逻辑类的耦合。
AOP仅作为OOP的有益补充。
具有横切逻辑的应用场合,如性能监控、访问控制、事务管理、日志记录。
如当某个方法需要进行性能监控时,必须调整方法代码,在方法体前后分别添加开启性能监控和结束性能监控的代码,这些非业务逻辑的性能监视代码破坏了业务类的纯粹性。通过代理的方式将业务方法中开启和结束性能监控的横切代码从业务类中完全移除,并通过JDK或CGLib动态代理技术将横切代码动态织入目标方法的相应位置。
Spring AOP使用动态代理技术在运行期织入增强的代码。动态代理技术常用如下两种。
主要涉及java.lang.reflect包中的两个类:Proxy和InvocationHandler。
InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑编织在一起。
Proxy利用InvacationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
CGLib采用底层的字节码技术,为类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。
实现MethodInterceptor接口,通过Enhancer为一个类创建动态代理对象,该代理对象通过扩展clazz实现代理,在该代理对象的intercept(Object obj, Method method, Object[] args,MethodProxy proxy)方法中,织入性能监视的横切逻辑。
JDK在创建代理对象时的性能高于CGLib,而生成的代理对象的运行性能却比CGLib的低。如果是singleton 的代理,则推荐使用CGLib动态代理。
特定点是程序执行的某个特定位置,如类开始初始化前、类初始化后、类的某个方法调用前/调用后、方法抛出异常后。
一个类或一段代码拥有一些具有边界性质的特定点,这些代码中的特定点就被称为“连接点”。连接点即特定点。
Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时及方法调用前后这些程序执行点织入增强。
连接点由两个信息确定:一是用方法表示的程序执行点;二是用相对位置表示的方位。如在Test.foo()执行前的连接点,执行点为Test.foo(),方位是方法执行前的位置。Spring使用切点对执行点进行定位,而方位则在增强类型中定义
AOP通过切点定位特定的连接点。
连接点相当于数据库中的记录,而切点相当于查询条件,切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
Spring通过Pointcut接口描述切点
增强是织入目标类连接点上的一段代码。
增强逻辑的织入目标类
引介是一种特殊的增强,它为类添加一些属性和方法。
织入是将增强添加到目标类的具体连接点上的过程。
AOP有3种织入方式
1.编译期织入,这要求使用特殊的Java编译器。
2.类装载器织入,这要求使用特殊的类装载器。
3.动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入。
一个类被AOP织入增强后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。
根据不通的代理方式,代理类既可能是和原类具有相同接口的类,也可能是原类的子类,所以可以采用与调用原类相同的方式调用代理类。
切面由切点和增强(引介)组成,它既包括横切逻辑的定义,它既包括横切逻辑的定义,也包括连接点的定义。
Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入切面所指定的连接点中。
org.springframework.aop.BeforeAdvice 前置增强,表示在目标方法前实施增强
org.springframework .aop.AfterReturningAdvice,表示在目标方法指向后实施增强
org.aopalliance.intercept.MethodInterceptor,表示在目标方法前后实施增强
org.springframework.aop. ThrowsAdvice,表示在目标方法抛出异常后实施增强
org.springframework.aop.IntroductionInterceptor,表示在目标类中添加一些新的方法和属性,引介增强接口IntroductionInterceptor没有定义任何方法,Spring为该类提供了默认实现类DelegatingIntroductionInterceptor,通过扩展该类定义自己的引介增强类。
maven配置文件在IOC的基础上新增AOP联盟、Spring AOP依赖包、CGLib依赖包。
4.0.0
com.fxy
spring
1.0-SNAPSHOT
war
spring Maven Webapp
UTF-8
1.8
1.8
4.3.14.RELEASE
4.0
3.0
org.springframework
spring-framework-bom
${spring.version}
pom
import
junit
junit
4.11
test
org.springframework
spring-core
org.springframework
spring-beans
org.springframework
spring-context
org.springframework
spring-expression
org.springframework
spring-aop
org.springframework
spring-aspects
aopalliance
aopalliance
1.0
org.ow2.asm
asm
${asm.version}
org.ow2.asm
asm-util
${asm.version}
cglib
cglib
${cglib.version}
asm
org.ow2.asm
新建PersonManageService接口及实现类PersonManageServiceImpl模拟人员的新增、变更、删除。代码如下
package com.fxy.spring.aop;
import com.fxy.spring.ioc.Person;
public interface PersonManageService {
public void add(Person p);
public void remove(Person p);
public void update(Person p);
}
package com.fxy.spring.aop;
import com.fxy.spring.ioc.Person;
public class PersonManageServiceImpl implements PersonManageService{
public void add(Person p){
PerformanceMonitor.begin("PersonManage.add");
System.out.println("模拟人员新增...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
PerformanceMonitor.end();
}
public void remove(Person p){
PerformanceMonitor.begin("PersonManage.remove");
System.out.println("模拟人员删除...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
if ("1".equals(p.getId())){
throw new RuntimeException("id为1人员不能删除");
}
PerformanceMonitor.end();
}
@Override
public void update(Person p) {
System.out.println("模拟人员变更...");
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
为每一个线程存储一个耗时监控对象
package com.fxy.spring.aop;
public class PerformanceMonitor {
private static ThreadLocal performaceRecord = new ThreadLocal();
public static void begin(String method) {
System.out.println("监控开始...");
MethodPerformace mp = performaceRecord.get();
if(mp == null){
mp = new MethodPerformace(method);
performaceRecord.set(mp);
}else{
mp.reset(method);
}
}
public static void end() {
System.out.println("监控结束...");
MethodPerformace mp = performaceRecord.get();
mp.printPerformace();
}
}
存储开始时间,结束时间,方法名。
public class MethodPerformace {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformace(String serviceMethod){
reset(serviceMethod);
}
public void printPerformace(){
end = System.currentTimeMillis();
long elapse = end - begin;
System.out.println(serviceMethod+"花费"+elapse+"毫秒。");
}
public void reset(String serviceMethod){
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 不使用代理,性能监控代码需要嵌入业务代码前后
*/
@Test
public void testOri(){
PersonManageServiceImpl pm = new PersonManageServiceImpl();
pm.add(new Person());
pm.remove(new Person());
}
}
监控开始...
模拟人员新增...
监控结束...
PersonManage.add花费101毫秒。
监控开始...
模拟人员删除...
监控结束...
PersonManage.remove花费200毫秒。
可以看到实现监控方法耗时的代码侵入方法内部,下面使用动态代理进行解耦。
package com.fxy.spring.aop;
import com.fxy.spring.ioc.Person;
public class PersonManageServiceImpl implements PersonManageService{
public void add(Person p){
System.out.println("模拟人员新增...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public void remove(Person p){
System.out.println("模拟人员删除...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
if ("1".equals(p.getId())){
throw new RuntimeException("id为1人员不能删除");
}
}
@Override
public void update(Person p) {
System.out.println("模拟人员变更...");
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
package com.fxy.spring.aop.jdk;
import com.fxy.spring.aop.PerformanceMonitor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformanceHandler implements InvocationHandler {
private Object target;//target为目标业务类
public PerformanceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName());
Object obj = method.invoke(target, args);//通过反射调用目标业务类的目标方法
PerformanceMonitor.end();
return obj;
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 测试jdk动态代理
*/
@Test
public void TestJdkProxy() {
PersonManageService target = new PersonManageServiceImpl();
PerformanceHandler handler = new PerformanceHandler(target);
PersonManageService proxy = (PersonManageService) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
Person person = new Person();
proxy.add(person);
proxy.remove(person);
}
}
执行结果
监控开始...
模拟人员新增...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl.add花费100毫秒。
监控开始...
模拟人员删除...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl.remove花费200毫秒。
无侵入的将耗时监控代码织入了业务方法前后,实现耗时监控的功能。
package com.fxy.spring.aop.cglib;
import com.fxy.spring.aop.PerformanceMonitor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);// 设置需要创建子类的类
enhancer.setCallback(this);
return enhancer.create();// 创建子类实例
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
PerformanceMonitor.begin(o.getClass().getName()+"."+method.getName());
Object result = methodProxy.invokeSuper(o, objects);//通过代理类调用父类中的方法
PerformanceMonitor.end();
return result;
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 测试cglib动态代理
*/
@Test
public void TestCglibProxy() {
CglibProxy proxy = new CglibProxy();
PersonManageServiceImpl personManageService = (PersonManageServiceImpl)proxy.getProxy(PersonManageServiceImpl.class);
Person person = new Person();
personManageService.add(person);
personManageService.remove(person);
}
}
执行结果:
监控开始...
模拟人员新增...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl$$EnhancerByCGLIB$$ef3e9fc6.add花费116毫秒。
监控开始...
模拟人员删除...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl$$EnhancerByCGLIB$$ef3e9fc6.remove花费200毫秒。
同样无侵入的将耗时监控代码织入了业务方法前后,实现耗时监控的功能。
package com.fxy.spring.aop.spring.advice;
import com.fxy.spring.aop.PerformanceMonitor;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class MonitorBeforeAdvicce implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
PerformanceMonitor.begin(o.getClass().getName()+"."+method.getName());
}
}
package com.fxy.spring.aop.spring.advice;
import com.fxy.spring.aop.PerformanceMonitor;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class MonitorAfterAdvicce implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
PerformanceMonitor.end();
}
}
package com.fxy.spring.aop.spring.advice;
import com.fxy.spring.aop.PerformanceMonitor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;
public class MonitorInterceptorAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object[] arguments = methodInvocation.getArguments();//获取入参
Object argument = arguments[0];
// System.out.println("入参:"+argument.toString());
System.out.println("环绕增强.....");
Object o = methodInvocation.getThis();
Method method = methodInvocation.getMethod();
PerformanceMonitor.begin(o.getClass().getName()+"."+method.getName());
Object proceed = methodInvocation.proceed();//通过反射调用目标方法
PerformanceMonitor.end();
return proceed;
}
}
package com.fxy.spring.aop.spring.advice;
import org.springframework.aop.ThrowsAdvice;
public class MonitorThrowsAdvice implements ThrowsAdvice{
public void afterThrowing(Exception ex){
System.out.println("捕获异常=="+ex.getMessage());
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 编码方式测试spring提供的aop
*/
@Test
public void tesSpringAOPAdvice1(){
PersonManageService target = new PersonManageServiceImpl();
MonitorBeforeAdvicce beforeAdvicce = new MonitorBeforeAdvicce();
MonitorAfterAdvicce afterAdvicce = new MonitorAfterAdvicce();
ProxyFactory pf = new ProxyFactory();
pf.setOptimize(true);// 使用cglibproxy
// pf.setInterfaces(target.getClass().getInterfaces());// 使用jdk proxy
pf.setTarget(target);
pf.addAdvice(beforeAdvicce);
pf.addAdvice(afterAdvicce);
PersonManageService proxy = (PersonManageService) pf.getProxy();
Person person = new Person();
proxy.add(person);
proxy.remove(person);
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 通过配置文件测试springaop中的前置增强、后置增强
*/
@Test
public void tesSpringAOPAdvice2(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageService");
Person person = new Person();
bean.add(person);
bean.remove(person);
}
/**
* 通过配置文件测试AOP联盟定义的环绕增强
*/
@Test
public void tesSpringAOPAdvice3(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageServiceInterceptor");
Person person = new Person();
bean.add(person);
bean.remove(person);
}
/**
* 通过配置文件测试异常抛出增强
*/
@Test
public void tesSpringAOPAdvice4(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageServiceInterceptor");
Person person = new Person();
person.setId("1");
bean.remove(person);
}
}
package com.fxy.spring.aop.spring.advisor;
import com.fxy.spring.aop.PersonManageServiceImpl;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import java.lang.reflect.Method;
public class MonitorStaticAdvisor extends StaticMethodMatcherPointcutAdvisor {
/**
* 切点方法匹配规则
* @param method
* @param aClass
* @return
*/
@Override
public boolean matches(Method method, Class aClass) {
return "add".equals(method.getName());
}
/**
* 切点类匹配规则
* @return
*/
@Override
public ClassFilter getClassFilter() {
return new ClassFilter() {
@Override
public boolean matches(Class aClass) {
return PersonManageServiceImpl.class.isAssignableFrom(aClass);//判断是否为某个类的父类
}
};
}
}
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
/**
* 测试静态普通方法名匹配切面
*/
@Test
public void tesMonitorStaticAdvisor(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageServiceStaticAdvisor");
Person person = new Person();
bean.add(person);
bean.remove(person);
}
}
.*add.*
.*remove.*
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
@Test
public void tesMonitorRegexpAdvisor(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageServiceRegexpAdvisor");
Person person = new Person();
bean.add(person);
bean.remove(person);
bean.update(person);
}
}
.*add.*
.*remove.*
package aop;
import com.fxy.spring.aop.cglib.CglibProxy;
import com.fxy.spring.aop.jdk.PerformanceHandler;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.advice.MonitorAfterAdvicce;
import com.fxy.spring.aop.spring.advice.MonitorBeforeAdvicce;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.Proxy;
public class TestAOP {
@Test
public void tesMonitorAutoProxy(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/autoAop.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageService");
Person person = new Person();
bean.add(person);
bean.remove(person);
bean.update(person);
}
}
package com.fxy.spring.aop.spring.aspectj;
public @interface MonitorAnnotation {
}
package com.fxy.spring.aop.spring.aspectj;
import com.fxy.spring.aop.PerformanceMonitor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MonitorAspect {
// 匹配所有标注了注解MonitorAnnotation的 add方法
@Before("@annotation(com.fxy.spring.aop.spring.aspectj.MonitorAnnotation) && execution(* add(..))")
public void before(JoinPoint jp){
Object target = jp.getTarget();
Signature signature = jp.getSignature();
String name = signature.getName();
PerformanceMonitor.begin(target.getClass().getName()+"."+name);
}
// 匹配所有标注了注解MonitorAnnotation的 add方法
@AfterReturning("@annotation(com.fxy.spring.aop.spring.aspectj.MonitorAnnotation) && execution(* add(..))")
public void after(){
PerformanceMonitor.end();
}
}
package com.fxy.spring.aop;
import com.fxy.spring.aop.spring.aspectj.MonitorAnnotation;
import com.fxy.spring.ioc.Person;
public class PersonManageServiceImpl implements PersonManageService{
@MonitorAnnotation
public void add(Person p){
System.out.println("模拟人员新增...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@MonitorAnnotation
public void remove(Person p){
System.out.println("模拟人员删除...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
if ("1".equals(p.getId())){
throw new RuntimeException("id为1人员不能删除");
}
}
@Override
public void update(Person p) {
System.out.println("模拟人员变更...");
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
package aop;
import com.fxy.spring.aop.PetManager;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.aspectj.MonitorAspect;
import com.fxy.spring.ioc.Cat;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAspectJAOP {
@Test
public void tesMonitorAspectj(){
PersonManageService target = new PersonManageServiceImpl();
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(target);
factory.addAspect(MonitorAspect.class);
PersonManageService proxy = (PersonManageService)factory.getProxy();
Person person = new Person();
proxy.add(person);
proxy.remove(person);
}
}
···
监控开始…
模拟人员新增…
监控结束…
com.fxy.spring.aop.PersonManageServiceImpl.add花费120毫秒。
模拟人员删除…
···
package aop;
import com.fxy.spring.aop.PetManager;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.aspectj.MonitorAspect;
import com.fxy.spring.ioc.Cat;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAspectJAOP {
@Test
public void tesMonitorAspectj2(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop-aspectj.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageService");
Person person = new Person();
bean.add(person);
bean.remove(person);
}
}
测试结果:
监控开始...
模拟人员新增...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl.add花费101毫秒。
模拟人员删除...
package aop;
import com.fxy.spring.aop.PersonManageService;
import com.fxy.spring.aop.PersonManageServiceImpl;
import com.fxy.spring.aop.spring.aspectj.MonitorAspect;
import com.fxy.spring.ioc.Cat;
import com.fxy.spring.ioc.Person;
import org.junit.Test;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAspectJAOP {
@Test
public void tesMonitorAspectj3(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:aop/aop-aspectj-auto.xml");
PersonManageService bean = (PersonManageService)context.getBean("personManageService");
Person person = new Person();
bean.add(person);
bean.remove(person);
}
}
测试结果:
监控开始...
模拟人员新增...
监控结束...
com.fxy.spring.aop.PersonManageServiceImpl.add花费101毫秒。
模拟人员删除...