项目结构
cglib 动态代理 ,其代理对象和目标对象是父子关系,因此代理对象可以直接调用目标对象的方法
com.zyj.proxy.cglib.Advice
package com.zyj.proxy.cglib; public class Advice { public void before(){ System.out.println("前置增强。。。。"); } public void afterReturning(){ System.out.println("后置增强。。。。"); } }
com.zyj.proxy.cglib.ProxyTest
package com.zyj.proxy.cglib; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import java.util.Calendar; public class ProxyTest { public static void main(String[] args) { //目标对象 final Target target = new Target(); //获得增强对象 Advice advice = new Advice(); //返回值 就是动态生成的代理对象 基于cglib //1、创建增强器 Enhancer enhancer = new Enhancer(); //2、设置父类(目标) enhancer.setSuperclass(target.getClass); //3、设置回调 enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //执行前置 advice.before(); //执行目标 Object invoke = method.invoke(target, args); //执行后置 advice.afterReturning(); return invoke; } }); //4、创建代理对象 Target proxy = (Target) enhancer.create(); proxy.save(); } }
com.zyj.proxy.cglib.Target
package com.zyj.proxy.cglib; public class Target { public void save() { System.out.println("save running......"); } }
运行结果
jdk 动态代理 ,其代理对象和目标对象是兄弟关系,两者不能进行类型转换,因此代理对象需要转为接口对象,再调用方法
com.zyj.proxy.jdk.Advice
package com.zyj.proxy.jdk; public class Advice { public void before(){ System.out.println("前置增强。。。。"); } public void afterReturning(){ System.out.println("后置增强。。。。"); } }
com.zyj.proxy.jdk.ProxyTest
package com.zyj.proxy.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) { //目标对象 final Target target = new Target(); //获得增强对象 Advice advice = new Advice(); //返回值 就是动态生成的代理对象 TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance( //目标对象类加载器 target.getClass().getClassLoader(), //目标对象相同的接口字节码对象数组 target.getClass().getInterfaces(), new InvocationHandler() { //调用代理对象的任何方法 实质执行的都是invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //前值增强 advice.before(); //执行目标方法 Object invoke = method.invoke(target, args); //后置增强 advice.afterReturning(); return invoke; } } ); //调用代理对象的方法 proxy.save(); } }
com.zyj.proxy.jdk.Target
package com.zyj.proxy.jdk; public class Target implements TargetInterface { @Override public void save() { System.out.println("save running......"); } }
com.zyj.proxy.jdk.TargetInterface
package com.zyj.proxy.jdk; public interface TargetInterface { public void save(); }
运行结果
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zyj</groupId> <artifactId>spring_aop</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>spring_aop Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> </dependencies> </project>