本文思路
- 动态代理在jdk、cglib、spring中如何实现的。
- spring实现动态代理的ProxyFactory详解。
- 从ProxyFactory的使用来了解AOP实现的大概思路。
什么是代理
- 为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。
- 常用的实现方式3种:jdk、cglib、spring的ProxyFactory。
如何创建动态代理的方式之JDK
UserService target = new UserService();
Object proxy = Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before...");
Object result = method.invoke(target, args);
System.out.println("after...");
return result;
}
});
UserInterface userService = (UserInterface) proxy;
userService.test();
如何创建动态代理的方式之cglib
UserService target = new UserService();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
Object result = methodProxy.invoke(target, objects);
System.out.println("after...");
return result;
}
}});
UserService userService = (UserService) enhancer.create();
userService.test();
如何创建动态代理的方式之spring的ProxyFactory
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();
Advice有哪些
- MethodBeforeAdvice:方法之前执行。可以new MethodBeforeAdvice重写before方法。
- AfterReturningAdvice:方法return后执行。可以new AfterReturningAdvice重写afterReturning方法。
- ThrowsAdvice:方法抛异常后执行。可以new ThrowsAdvice重写afterThrowing方法。afterThrowing的第四个参数是具体的异常,会进行异常的匹配。
- After (finally) advice:方法执行完finally之后执行,这是最后的,比return更后。
- MethodInterceptor:环绕执行这是功能最强大的Advice,可以自定义执行顺序。可以new MethodInterceptor重写invoke方法。
Advisor:在Advice基础上增加了判断!
- Advisor是有一个Pointcut和一个Advice组成。
- 通过Pointcut可以指定要需要被代理的逻辑。比如可以指定那个类的那个方法进行代理。
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return method.getName().equals("testAbc");
}
};
}
@Override
public Advice getAdvice() {
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
};
}
@Override
public boolean isPerInstance() {
return false;
}
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();
让动态代理的对象成为Bean:ProxyFactoryBean
@Bean
public ProxyFactoryBean userService(){
UserService userService = new UserService();
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(userService);
proxyFactoryBean.setInterceptorNames("zhangweiAroundAdvise");
return proxyFactoryBean;
}
@Bean
public MethodInterceptor zhangweiAroundAdvise(){
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
};
}
解决让Bean不需要自己指定代理逻辑,降低耦合度:BeanNameAutoProxyCreator
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("userSe*");
beanNameAutoProxyCreator.setInterceptorNames("zhangweiAroundAdvise");
beanNameAutoProxyCreator.setProxyTargetClass(true);
return beanNameAutoProxyCreator;
}
解决BeanNameAutoProxyCreator只能根据BeanName进行匹配:可以进行方法匹配的DefaultAdvisorAutoProxyCreator
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor(){
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("test");
DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new ZhangweiAfterReturningAdvise());
return defaultPointcutAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
return defaultAdvisorAutoProxyCreator;
}
再次进行简化:@Aspect
@Aspect
@Component
public class ZhangweiAspect {
@Before("execution(public void com.zhangwei.service.UserService.test())")
public void zhangweiBefore(JoinPoint joinPoint) {
System.out.println("zhangweiBefore");
}
}
结束语
- 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
- 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
- 关注公众号,后续持续高效的学习JVM!
- 这个公众号,无广告!!!每日更新!!!

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码