Spring中AOP创建代理的方法
发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!1、准备创
千家信息网最后更新 2025年01月23日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(); List
public 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(); } //获取当前方法的拦截器链 Listchain = 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安全错误
数据库的锁怎样保障安全
我的世界服务器推荐管理
上海益美网络技术有限公司
工控软件开发PPT
上海恒派网络技术厦门
为什么大脚插件不能连接服务器
湖北公安厅网络安全总队
软件开发费用应入哪个科目
企业级服务器安全
服务器扒包
中国移动游戏服务器
如何删除数据库账户
云南电网公司违章数据库
坪山区网络技术转移好处
苏州中移动软件开发薪资
工业企业数据库国有控股情况
手机同声翻译软件开发
四川菜小白网络技术
史上最垃圾的游戏服务器
负债众筹平台软件开发商
西安四叶草网络技术公司
系统网络安全证书
深圳群控云控软件开发商
东洋文库 数据库
软件开发软件工程师培训
服务器温度检测软件
bzz 服务器ip
工业网络技术教材
紫宁数据库
防网络安全手抄报版面一等奖
服务器的端点URL是什么