Spring有选择地使用实现而不是接口

时间:2017-10-18 09:34:48

标签: java spring spring-mvc

无法找到明确的答案,所以在这里问一下 - 是否可以只为一个bean打开CGLIB代理?方案如下 - 我有一个自动装配的类,并且没有实现任何接口,现在我想添加一个接口,它将覆盖它的一小部分方法。是否可以使用CGLIB仅代理这个类,而不影响Spring的默认行为(首选JDK动态代理)?
我使用的是基于java的配置。

1 个答案:

答案 0 :(得分:1)

(目前)没有任何支持开箱即用,可以为单个类启用基于类的代理。相反,您必须自己创建代理。这样做的缺点是你需要一些关于Spring如何工作的熟悉知识(我碰巧有:) :)。

您应该/可以使用ProxyFactoryProxyFactoryBean为您的给定类创建基于类的代理。您的@Bean方法将返回代理而不是实际的类。然后,Spring非常聪明(至少它应该)来检测它已经是代理,而不是再次代理它,它应该将建议添加到已经创建的代理。为了使这项工作不破坏自动布线和Spring给你的所有其他好处,你可能想要创建一个特定的BeanPostProcessor来处理这个问题。

public YourBeanPostProcessor implements BeanPostProcessor {

    public  Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof YourBean) {
            ProxyFactory factory = new ProxyFactory(bean);
            factory.setProxyTargetClass(true);
            return factory.getProxy();
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

将此注册为bean,就像通常使用BeanPostProcessor一样。

@Bean
public static YourBeanPostProcessor yourBeanPostProcessor() {
    return new YourBeanPostProcessor();
}

现在你有一个预先创建的基于类的代理,应该由Spring检测和使用。