Spring中AOP创建代理的方法
发表于:2024-09-25 作者:千家信息网编辑
千家信息网最后更新 2024年09月25日,这篇文章主要讲解了"Spring中AOP创建代理的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring中AOP创建代理的方法"吧!1、准备创
千家信息网最后更新 2024年09月25日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安全错误
数据库的锁怎样保障安全
枣庄软件开发多少钱
数据库中文件怎样转化成文档
高新区品质网络技术
王者苹果服务器充值要银行卡吗
医院管理系统云服务器
软件开发者感言
网络安全播报词
软件开发需要会数学吗
张湾区互联网软件开发售后保障
tp5数据库字段减1
韶关市网络安全问题
天津景晨网络技术咨询
广东专业软件开发设施检测中心
网络安全法正式实行是哪一天
搭建sk5显示被服务器放弃
sql c 写入数据库
方舟生存如何在网吧建服务器
手机网络安全模式怎么选
互联网科技风格ppt
明日之后韵哥是哪个服务器的
海关网络安全培训中心
顺义区网络技术服务概况
街道学习网络安全法简报
龙之神途最好玩服务器
软件开发项目总监岗位职责
数据库2012怎么修改
明日之后全版本服务器
服务器到期
网络安全工程师证 中级
sip软件开发