如何让Spring Controllers,AOP和JDK Proxy协同工作

时间:2012-12-10 22:51:13

标签: spring proxy controller spring-aop cglib

在我的spring控制器中,注释了方面,我试图删除CGLib代理并用JDK动态代理替换它们。我知道Spring AOP在类没有实现接口时使用CGLib,因为JDK动态代理仅在接口上工作。我也意识到注释需要出现在接口和实现类上。但是,我遇到的问题是控制器不再显示为带有JDK代理的bean。

扫描我的控制器bean是这样的:

<context:annotation-config/>
<context:component-scan base-package="com.package.name"/>

这样可行,但控制器显示为CGLibController $$ EnhancerByCGLIB $$ 5f0b2287:

package com.package.name;
@Controller
public class CGLibController {
  @AOP_Aspect
  @RequestMapping("some_url")
  public void foo();
}

//in a bean post processor
//in postProcessAfterInitialization(Object bean, String beanName)
  Controller controller = AnnotationUtils
      .findAnnotation(bean.getClass(), Controller.class);
//controller will exist
//bean name is CGLibController$$EnhancerByCGLIB$$5f0b2287

这不起作用,它永远不会进入bean后处理器:

package com.package.name;
@Controller
public interface ITest{
  @AOP_Aspect
  @RequestMapping("some_url")
  public void foo();
}

package com.package.name;
@Controller
public class DynamicController implements ITest{
  @AOP_Aspect
  @RequestMapping("some_url")
  public void foo();
}

但是,如果我在

中显式创建此DynamicController bean
<bean class="com.package.name.DynamicController"/>

然后当我启动我的服务器时,ServletContext会抱怨

  

bean初始化失败;嵌套异常是   java.lang.IllegalStateException:无法映射处理程序   'dynamicController'到URL路径[some_url]:已有处理程序   [class $ Proxy61]类型映射。

这里发生了一些事情,DynamicController是一个动态代理。但我不知道还发生了什么,我知道它不再是一个bean /控制器了。我不想要“控制器,方面,动态代理:挑选任何两个”我想要三个。这有可能吗?

2 个答案:

答案 0 :(得分:0)

我不是100%确定您的BeanPostProcessor正在尝试做什么,或者如果您控制其中的代码,但似乎可以安全地假设它不是Ordered,因此它在创建代理后被处理(哪个会有默认的最低优先级,但在无序之前)。也许你可以实现Ordered并给它一个低阶(如0)?

答案 1 :(得分:0)

为了获取这个bean,我必须在postProcessBeforeInitialization中处理它,而不是像之前那样在postProcessAfterInitialization中处理它。我推测它在初始化时被代理并且会弄乱某些东西。

正如我所暗示的那样,DynamicController实际上是一个JDK动态代理,但代理背后的真正对象是bean。然而!当使用代理和编程到接口时,根据我丢失的一些来源,注释必须在接口上。没有它们在界面上,春天不会知道。并且注释必须在具体类上才能使bean后处理器工作,仅在接口上是不够的。