一、基础接口和类
1、Person接口的源码
public interface Person { public void info(); public void show(String message); }
2、PersonImpl类的源码
public class PersonImpl implements Person { private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void info() { System.out.println("\t我叫" + name + ",今年" + age + "岁。"); } public void show(String message) { System.out.println(message); } }
3、bean的配置
<!-- 目标对象 --> <bean id="personTarget" class="com.cjm.aop.PersonImpl"> <property name="name" value="Raymond.chen"/> <property name="age" value="30"/> </bean>
二、Spring AOP支持的通知类型
一)环绕通知(Around advice)
实现环绕通知需要实现org.aopalliance.intercept.MethodInterceptor接口。
1、PersonAroundAdvice类的源码
public class PersonAroundAdvice implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("AroundAdvice:方法调用前"); //不要忘记调用invocation的proceed方法哦 Object result = invocation.proceed(); System.out.println("AroundAdvice:方法调用后"); return result; } }
2、bean配置
<bean id="personAroundAdvice" class="com.cjm.aop.PersonAroundAdvice"/> <!-- 代理工厂bean --> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personAroundAdvice</value> </list> </property> </bean>
3、测试代码
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:com/cjm/aop/beans.xml"); Person p = (Person)context.getBean("person"); //注意这里是代理工厂Bean的ID p.info();
二)前置通知(Before advice)
实现前置通知需要实现org.springframework.aop.MethodBeforeAdvice接口。
1、PersonBeforeAdvice类的源码
public class PersonBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("BeforeAdvice:方法调用前"); } }
2、bean配置
<bean id="personBeforeAdvice" class="com.cjm.aop.PersonBeforeAdvice"/> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personBeforeAdvice</value> </list> </property> </bean>
三)返回后通知(After Returning advice)
实现返回后通知需要实现org.springframework.aop.AfterReturningAdvice接口。
1、PersonAfterReturningAdvice类的源码
public class PersonAfterReturningAdvice implements AfterReturningAdvice { public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("AfterReturningAdvice:方法调用后"); } }
2、bean配置
<bean id="personAfterReturningAdvice" class="com.cjm.aop.PersonAfterReturningAdvice"/> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personAfterReturningAdvice</value> </list> </property> </bean>
3、以上的配置中,通知对目标对象的所有方法都会起作用。如果需要过滤掉一部分方法,可以用正则表达式切入点配置器或者方法名匹配切入点配置器实现。
<!-- 通知与正则表达式切入点一起配置 --> <!-- Advisor等于切入点加通知 --> <!-- 方法名匹配切入点配置器:org.springframework.aop.support.NameMatchMethodPointcutAdvisor --> <bean id="personPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="personAfterReturningAdvice"/> <property name="patterns"> <list> <value>.*info.*</value> </list> </property> </bean> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personPointcutAdvisor</value> </list> </property> </bean>
四)异常通知(Throws advice)
当连接点抛出异常时,异常通知被调用。实现异常通知需要实现org.springframework.aop.ThrowsAdvice接口,该接口不包含任何方法,但在实现该接口时必须实现如下形式的方法:
afterThrowing([Method], [args], [target], Throwable subclass)
可以实现一个或多个这样的方法。在这些方法中,只有第四个参数是必需的,前三个参数可选。
1、PersonThrowsAdvice类的源码
public class PersonThrowsAdvice implements ThrowsAdvice { public void afterThrowing(FileNotFoundException ex){ System.out.println("ThrowsAdvice >> FileNotFoundException:" + ex.toString()); } public void afterThrowing(Object[] args, Exception ex){ System.out.println("ThrowsAdvice >> Exception:" + ex.getMessage()); } public void afterThrowing(Method method, Object[] args, Object target, Throwable ex){ System.out.println("ThrowsAdvice >> Throwable:" + ex.getMessage()); } }
2、bean配置
<bean id="personThrowsAdvice" class="com.cjm.aop.PersonThrowsAdvice"/> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personThrowsAdvice</value> </list> </property> </bean>
五)引入通知(Introduction advice)
引入通知是一种特殊的通知,它能将新的成员变量、成员方法引入到目标类中。它不能作用于任何切入点,因为它只作用于类层次,而不是方法层次。实现引入通知需要实现IntroductionAdvisor和IntroductionInterceptor接口。
引入通知不能调用proceed方法。Advisor必须针对每个实例,并且是有状态的。
引入通知的效果类似于设计模式中的访问者模式(Visitor Pattern)。
//类的继承关系 DelegatingIntroductionInterceptor IntroductionInfoSupport IntroductionInfo IntroductionInterceptor MethodInterceptor Interceptor Advice DynamicIntroductionAdvice Advice DefaultIntroductionAdvisor IntroductionAdvisor Advisor IntroductionInfo ClassFilter Ordered
1、Lockable接口的源码
public interface Lockable { void lock(); void unlock(); boolean locked(); }
2、LockableImpl类的源码
public class LockableImpl extends DelegatingIntroductionInterceptor implements Lockable { private boolean locked; public void lock() { this.locked = true; } public void unlock() { this.locked = false; } public boolean locked() { return this.locked; } @Override public Object invoke(MethodInvocation invocation) throws Throwable { if(this.locked){ throw new RuntimeException("加锁,无法执行"); } //这里不能调用invocation的proceed方法 //通常不需要改写invoke方法,直接调用父类的该方法即可 return super.invoke(invocation); } }
3、PersonIntroductionAdvice类的源码
public class PersonIntroductionAdvice extends DefaultIntroductionAdvisor { public PersonIntroductionAdvice(){ super(new LockableImpl(), Lockable.class); } }
4、bean配置
<!-- Advice必须针对每个实例,所以scope要设为prototype --> <bean id="personIntroductionAdvice" class="com.cjm.aop.introduction.PersonIntroductionAdvice" scope="prototype"/> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.cjm.aop.Person"/> <property name="target" ref="personTarget"/> <property name="interceptorNames"> <list> <value>personIntroductionAdvice</value> </list> </property> </bean>
5、测试代码
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:com/cjm/aop/beans.xml"); //获得目标bean的代理bean Person p = (Person)context.getBean("person"); //执行代理bean的方法,此时并未调用lock方法,可以执行 p.info(); Lockable lockable = (Lockable)p; lockable.lock(); //目标bean已被锁定,此处将抛出异常 p.info();
相关推荐
Spring AOP 入门 作者:廖雪峰
Maven坐标:org.springframework:spring-aop:5.0.10.RELEASE; 标签:spring、aop、springframework、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...
Spring基础:Spring AOP简单使用
通过对SRPING aop的使用和研究,总结出来的SPRING AOP使用原理,以及在使用spring aop过程中要注意的问题
Spring源码最难问题:当Spring AOP遇上循环依赖.docx
Spring Aop的使用实例
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
spring aop jar 包
Spring AOP面向方面编程原理:AOP概念,主要介绍面向对象的概念及原理,及作者的一些理解。
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
NULL 博文链接:https://czj4451.iteye.com/blog/2051461
一、适合人群 1、具备一定Java编程基础,初级开发者 2、对springboot,mybatis,mysql有基本认识 3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 ...4、spring boot,mybatis,druid,spring aop的使用
里面包括4个例子:(1)Spring实现AOP方式之一:基于XML配置的Spring AOP (2)Spring实现AOP方式之二:使用注解配置 Spring AOP (3)Spring AOP : AspectJ Pointcut 切点 (4)Spring AOP : Advice 声明 (通知注解)
使用SpringAop使用Oracle数据权限控制
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
Spring AOP简单demo 入门级的 advice
压缩包中函数Spring AOP开发时使用注解和xml文件配置demo
Maven坐标:org.springframework:spring-aop:5.2.0.RELEASE; 标签:springframework、spring、aop、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...