jdk动态代理
只能针对接口进行代理,主要类InvocationHandler,Proxy
代理的接口
public interface ForumService {
void removeTopic(int topicId);
void removeForum(int forumId);
}
接口实现类,后面需要被增强的类
public class ForumServiceImpl implements ForumService{
@Override
public void removeTopic(int topicId) {
System.out.println("记录topicId"+topicId);
}
@Override
public void removeForum(int forumId) {
System.out.println("记录forumId"+forumId);
}
}
代理逻辑实现 InvocationHandler
public class PerformanceHandler implements InvocationHandler {
private Object target;
public PerformanceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy 代理对象 method 执行的反射方法 args方法参数
System.out.println("执行前");
Object invoke = method.invoke(target, args);
System.out.println("执行后");
return invoke;
}
}
使用代理
public class test {
public static void main(String[] args) {
//被代理的原对象
ForumServiceImpl target = new ForumServiceImpl();
//初始化handler
PerformanceHandler performanceHandler = new PerformanceHandler(target);
//实际代理对象
ForumService o = (ForumService)Proxy
.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
performanceHandler);
o.removeTopic(100);
o.removeForum(200);
}
}
CGLib动态代理
针对类的代理,动态生成代理子类,无法对final类或者private方法代理
需要依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
java9以后反射被限制需要再jvm参数添加
--add-opens java.base/java.lang=ALL-UNNAMED
代理类
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 {
//o为目标类实例,methot为方法反射对象,objects为方法参数,methodProxy为代理的对象
System.out.println("执行前");
Object o1 = methodProxy.invokeSuper(o, objects);
System.out.println("执行后");
return o1;
}
}
使用
public class test1 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
//这里是获取代理后的对象
ForumServiceImpl proxy = (ForumServiceImpl)cglibProxy.getProxy(ForumServiceImpl.class);
proxy.removeForum(100);
proxy.removeTopic(200);
}
}
总结
- 动态代理为spring Aop的底层原理,原生的对所有的方法都进行了代理,对于每个接口或类都要手动编写代理类,无法通用。通过硬编码指定了织入点
- Cglib创建的对象性能比jdk的性能高10倍左右,但是创建对象的速度却比jdk的创建速度慢8倍左右,所以在单例或者有池的情况下用Cglib方式更好
版权声明:本文为weixin_44316557原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。