Spring中AOP创建代理的方法
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!1、准备创
千家信息网最后更新 2025年12月02日Spring中AOP创建代理的方法
这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!
1、准备创建代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //1.寻找增强器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { //2.创建代理 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); return proxy; }}protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) { //第六篇AOP寻找增强器已经分析了该步骤 List advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray();}protected Object createProxy(Class> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { //对于代理类的创建及处理,交给了ProxyFactory去处理,此函数中只是做一些准备工作 ProxyFactory proxyFactory = new ProxyFactory(); //获取当前类中相关属性 proxyFactory.copyFrom(this); if (!shouldProxyTargetClass(beanClass, beanName)) { //形如interface com.lwh.spring.JdkProxy.PersonService Class>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader); for (Class> targetInterface : targetInterfaces) { //添加代理接口 proxyFactory.addInterface(targetInterface); } } //将拦截器封装为增强器,此处的拦截器类型就是增强器 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { //并添加到ProxyFactory中 proxyFactory.addAdvisor(advisor); } //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@1130520d] proxyFactory.setTargetSource(targetSource); //定制代理,空实现,由子类实现 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //创建代理 return proxyFactory.getProxy(this.proxyClassLoader);}protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) { Advisor[] commonInterceptors = resolveInterceptorNames(); Listpublic Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { if (adviceObject instanceof Advisor) { return (Advisor) adviceObject; } if (!(adviceObject instanceof Advice)) { throw new UnknownAdviceTypeException(adviceObject); } Advice advice = (Advice) adviceObject; if (advice instanceof MethodInterceptor) { return new DefaultPointcutAdvisor(advice); } for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { return new DefaultPointcutAdvisor(advice); } } throw new UnknownAdviceTypeException(advice);}2、创建代理
return proxyFactory.getProxy(this.proxyClassLoader);public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader);}protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this);}//此函数真正完成了代理的创建public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //三个条件影响Spring的判断 //1.optimize属性,不推荐用户使用这个设置 //2.proxytargetclass属性,之前分析过 //3.是否存在代理接口 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)){ Class targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { //使用JDK动态代理 return new JdkDynamicAopProxy(config); } return CglibProxyFactory.createCglibProxy(config); } else { //目标对象实现了接口,默认使用JDK动态代理 return new JdkDynamicAopProxy(config); }}3、获取代理
public Object getProxy(ClassLoader classLoader) { //先是创建代理,再是获取代理 return createAopProxy().getProxy(classLoader);}public Object getProxy(ClassLoader classLoader) { //获取代理接口,此处其实就是JDK的动态代理实现了,建议复习下JDK的动态代理 Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //返回代理对象 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}JDK动态代理的关键就是实现InvocationHandler方法并实现其invoke方法,而此处的JdkDynamicAopProxy实现了InvocationHandler接口,所以其中一定有invoke方法. 看笔记得知,获取到的是代理对象PersonService personService = ctx.getBean("personService", PersonService.class);此处实际调用的是生成的代理类中的sayHello方法,看下图,因为是之前做的笔记,所以包名不一致,但意思很明显,在代理类中sayHello方法又会调用InvocationHandler中的invoke方法,此h对象,即InvocationHandler是在Proxy.newProxyInstance时设置进去的,所以下面调用sayHello方法时先会进入JdkDynamicAopProxy的invoke方法personService.sayHello();
4、分析方法调用
//获取代理对象PersonService personService = ctx.getBean("personService", PersonService.class);//方法调用personService.sayHello();public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852] TargetSource targetSource = this.advised.targetSource; Class targetClass = null; Object target = null; try { //删去了部分代码 Object retVal; //SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852] target = targetSource.getTarget(); if (target != null) { //class com.lwh.spring.JdkProxy.PersonServiceImpl targetClass = target.getClass(); } //获取当前方法的拦截器链 List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); if (chain.isEmpty()) { //如果链为空,直接调用切点方法 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { //将拦截器封装在ReflectiveMethodInvocation中,以便于使用其proceed方法进行链接调用 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //执行拦截器链调用 retVal = invocation.proceed(); } Class> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { } return retVal; } finally { }} public Object proceed() throws Throwable { // We start with an index of -1 and increment early. //执行完所有增强方法后执行切点方法,维护了一个currentInterceptorIndex计数器,递增 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } //List interceptorsAndDynamicMethodMatchers,记录了要执行的增强方法,通过下标获取要执行的增强方法 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); }}感谢各位的阅读,以上就是"Spring中AOP创建代理的方法"的内容了,经过本文的学习后,相信大家对Spring中AOP创建代理的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
代理
方法
拦截器
动态
对象
接口
就是
增强器
属性
分析
学习
内容
函数
切点
笔记
准备
处理
封装
明显
一致
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库三星note7
手机网络安全故事
航天软件开发人员的职责
澳洲软件开发公司创业史
武义软件开发班
二维码如何输入数据库
太原高科技法治文化展馆软件开发
塘厦服务器专卖店
宝塔服务器管理系统好用吗
重庆妙享网络技术股份
当前网络安全系数低
软件系统 数据库 接口代码
怀旧服服务器里的插件怎么下载
重庆梁平生鲜管理软件开发
高级网络安全管理师一般多少分过
软件开发合同未完成纠纷
魏县直销网络推广需要服务器吗
北大法宝数据库
网络技术基础pk
2020三级数据库技术目录
深圳weiqiao网络技术
网络安全专业工作方向
实时数据库开发
华三服务器关机风扇转
天猫购物车下单服务器出错怎么办
关于重视网络安全的手抄报
新余游戏软件开发公司电话
网格数据库管理
服务器系统怎么关闭组合键
丰台科技园互联网