参考:Spring Framework Reference Documentation
静态代理、JDK与CGLIB动态代理、AOP+IoC - 张果 - 博客园
使用ProxyFactoryBean创建Aop代理
ProxyFactoryBean的几个属性
proxyTargetClass:默认为false,使用JDK动态代理,true则为使用CgLib动态代理。
interceptorNames:Advice,拦截器或其他Advice名称的字符串数组。
target:目标类
java方式
前置通知
public class BeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("-----------前置通知--------------"); } }
环绕通知
public class SurroundAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("方法" + invocation.getMethod() + " 被调用在对象" + invocation.getThis() + "上,参数 " + invocation.getArguments()); Object object = invocation.proceed(); System.out.println("返回值 "+object); return object; } }
相关的实体类
public class Math{ //加 public int add(int n1,int n2){ int result=n1+n2; System.out.println(n1+"+"+n2+"="+result); return result; } //减 public int sub(int n1,int n2){ int result=n1-n2; System.out.println(n1+"-"+n2+"="+result); return result; } //乘 public int mut(int n1,int n2){ int result=n1*n2; System.out.println(n1+"X"+n2+"="+result); // throw new RuntimeException(); return result; } //除 public int div(int n1,int n2){ int result=n1/n2; System.out.println(n1+"/"+n2+"="+result); return result; } }
Main类
public class Main { public static void main(String[] args) { //实例化Spring代理工厂 //实例化Spring代理工厂 ProxyFactory factory=new ProxyFactory(); //设置被代理的对象 factory.setTarget(new Math()); //添加通知,横切逻辑 factory.addAdvice(new BeforeAdvice()); factory.addAdvice(new SurroundAdvice()); //从代理工厂中获得代理对象 IMath math=(IMath) factory.getProxy(); int n1=100,n2=5; math.add(n1, n2); math.sub(n1, n2); math.mut(n1, n2); math.div(n1, n2); } }
输出
-----------前置通知-------------- 方法public int com.jxufe.study.spring.util.Math.add(int,int) 被调用在对象com.jxufe.study.spring.util.Math@3b22cdd0上,参数 [Ljava.lang.Object;@13a57a3b 100+5=105 返回值 105 -----------前置通知-------------- 方法public int com.jxufe.study.spring.util.Math.sub(int,int) 被调用在对象com.jxufe.study.spring.util.Math@3b22cdd0上,参数 [Ljava.lang.Object;@4de8b406 100-5=95 返回值 95 -----------前置通知-------------- 方法public int com.jxufe.study.spring.util.Math.mut(int,int) 被调用在对象com.jxufe.study.spring.util.Math@3b22cdd0上,参数 [Ljava.lang.Object;@3c756e4d 100X5=500 返回值 500 -----------前置通知-------------- 方法public int com.jxufe.study.spring.util.Math.div(int,int) 被调用在对象com.jxufe.study.spring.util.Math@3b22cdd0上,参数 [Ljava.lang.Object;@7c0e2abd 100/5=20 返回值 20
xml方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="target" class="com.jxufe.study.spring.util.Math"/> <bean id = "advice" class="com.jxufe.study.spring.aop.AfterAdvice"/> <bean id = "surroundAdvice" class="com.jxufe.study.spring.aop.SurroundAdvice"/> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interceptorNames" > <list> <value>advice</value> <value>surroundAdvice</value> </list> </property> <property name="target" ref="target"/> <property name="proxyTargetClass" value="true"> </property> </bean> </beans>
Main类
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml"); IMath math = (IMath) context.getBean("proxy"); int n1=100,n2=5; math.add(n1, n2); math.sub(n1, n2); math.mut(n1, n2); math.div(n1, n2);