当前位置: 首页 > news >正文

大学文明校园网站建设方案找资源

大学文明校园网站建设方案,找资源,社交电商系统开发,推荐购物网站建设一、现象 SpringMVC中controller里的private接口中注入的service层的bean为null,而同一个controller中访问修饰符为public和protected的方法不会出现这样的问题。 controller中的方法被AOP进行了代理,普通Controller如果没有AOP,private方法…

一、现象

SpringMVC中controller里的private接口中注入的service层的bean为null,而同一个controller中访问修饰符为public和protected的方法不会出现这样的问题。

controller中的方法被AOP进行了代理,普通Controller如果没有AOP,private方法中bean也是正常的。

二、原因分析

因为没有AOP增强的private方法是正常的,所以我们可以联想到可能是因为创建了代理对象的原因导致的属性为空。

首先SpringAOP有两种实现方式,一种是Jdk动态代理,一种是Cglib动态代理。

这两种方式一种是通过对接口的实现,一种是通过创建子类重写,那么显然这两种方式都是无法代理私有方法的。

创建代理对象时会经过这么一段逻辑Enhancer#generateClass -> Enhancer#getMethods -> CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true)) -> VisibilityPredicate#evaluate

public boolean evaluate(Object arg) {Member member = (Member)arg;int mod = member.getModifiers();if (Modifier.isPrivate(mod)) {return false;} else if (Modifier.isPublic(mod)) {return true;} else if (Modifier.isProtected(mod) && this.protectedOk) {return true;} else {return this.samePackageOk && this.pkg.equals(TypeUtils.getPackageName(Type.getType(member.getDeclaringClass())));}
}

可以看到其中将私有方法进行了过滤,即创建的代理对象中并不会增强private方法

Spring中使用@Aspect注解会注册一个后置处理器,在Bean初始化时判断是否需要创建代理(主要逻辑在wrapIfNecessary方法中)。而我们都知道Bean在属性赋值时便将属性的依赖都注入了,所以此时的Bean中service层的bean是完成填充了的。

那为什么会出现调用private方法空指针异常呢?

这是因为为该类创建的代理并没有完成bean的生命周期,所以其中的属性是null。private方法并没有被真正的代理类拦截(如前面所说被过滤了),因此private方法无法获取被代理的对象,所以使用的是代理对象去调用的方法,而代理对象是由Cglib创建的并没有注入bean对象,所以出现了空指针异常。

而当调用被增强了的方法(即在代理类中重写了的方法)时,其实传入的并非代理的实例对象,而是target,即被代理的Bean的实例对象,所以才能取得service层的bean。

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 省略...target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = invokeMethod(target, method, argsToUse, methodProxy);}else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal = processReturnType(proxy, target, method, retVal);return retVal;// 省略...}
}static boolean isMethodProxyCompatible(Method method) {return (Modifier.isPublic(method.getModifiers()) &&method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
}

从注释也可以看出,当调用public方法时“just reflective invocation of the target“,即只是对目标的反射调用

http://www.khdw.cn/news/6294.html

相关文章:

  • 彩票网站怎么做系统域名收录查询
  • 项城市建设方案公示在哪个网站市场营销的对象有哪些
  • 清远网站开发公司河北高端网站建设
  • bbs建站如何用google搜索产品关键词
  • 阜阳建设工程质量监督网站百度企业网盘
  • 外国人做外贸都会浏览哪些网站龙岗百度快速排名
  • 威海精神文明建设办公室网站网络关键词排名软件
  • 网站百度搜索情况和反链接优化建议网址最新连接查询
  • 河南网站推广优化公司百度最怕哪个部门去投诉
  • 刚刚廊坊发生大事了乐云seo官网
  • be 设计网站营销型网站内容
  • 西双版纳傣族自治州属于哪个市自学seo能找到工作吗
  • 帮客户做违法网站违法么软文代写价格
  • 无锡网站排名优化费用山西搜索引擎优化
  • 青少年宫网站开发最近有哪些新闻
  • 做日本贸易哪个网站好刷移动关键词优化
  • seo诊断网站免费诊断平台关键词站长工具
  • 自己做网站哪里最好杭州优化外包
  • 上海做网站哪里有网页模板建站系统
  • 广州腾虎网络网站建设熊掌号百度问答官网
  • 简述网站制作流程图外国网站开放的浏览器
  • 重庆网站设计公司网站制作信息流优化师发展前景
  • 网站建设的主要内容抖音引流推广一个30元
  • 小精灵网站在线做语文seo运营经理
  • 无经验可以做网站编辑吗手游推广平台
  • 怎么做网站反向链接bing收录提交
  • 泰州模板开发建站2023年8月新冠又来了
  • 悉知网站建设百度关键词收录排名
  • 西安手机网站定制网站建设求个没封的网站2022
  • 网站弄论坛形式怎么做白山网络推广