Java Bean light模式配置如何在Bean上创建代理
我读了一部分关于@Bean Lite模式的spring文档 据我所知,如果config被注释为component,那么spring不会创建该config的代理类,并且该类中所有配置的bean都被视为普通方法调用。然而,根据这个例子,Spring为bean创建了代理,该bean被注释为@Transactional,并在@Component类中配置Java Bean light模式配置如何在Bean上创建代理,java,spring,spring-boot,Java,Spring,Spring Boot,我读了一部分关于@Bean Lite模式的spring文档 据我所知,如果config被注释为component,那么spring不会创建该config的代理类,并且该类中所有配置的bean都被视为普通方法调用。然而,根据这个例子,Spring为bean创建了代理,该bean被注释为@Transactional,并在@Component类中配置 @SpringBootApplication public class TranslatorApplication implements Command
@SpringBootApplication
public class TranslatorApplication implements CommandLineRunner {
@Autowired
ProxyBean bean;
@Autowired
Conf conf;
public static void main(final String[] args) {
SpringApplication.run(TranslatorApplication.class, args);
}
@Override
public final void run(final String... args) {
System.out.println(conf.getClass().getSimpleName());
System.out.println(bean.getClass().getSimpleName());
}
@Component
static class Conf {
@Bean
public ProxyBean bean() {
return new ProxyBean();
}
}
static class ProxyBean {
@Transactional
public void init() {
}
}
}
输出:
Conf
TranslatorApplication$ProxyBean$$EnhancerBySpringCGLIB$$f4c1a493
这意味着ProxyBean是由CGLIB创建的代理。
问题是,如果配置类不是代理,那么Spring如何为方法公共ProxyBean()
创建代理?
Spring Boot版本-2.1.6我将尝试解释一下
若配置被注释为组件,那个么spring不会创建代理
此配置的类
Spring容器仅在需要时为bean创建代理,就像对bean的任何特殊处理一样,例如:AOP、事务管理。我已经为另一个SO问题解释了这一点,如果有兴趣,请浏览答案的A2部分
因此,例如,如果用@Transactional
注释类,那么Conf
类bean将是一个代理
此类中所有配置的bean都被视为普通方法
召唤
不对。Lite模式中的所有自调用或内部方法调用都是普通方法调用,而不是用@Configuration
注释的类中的特殊处理。在@Configuration
注释类中,对@Bean
注释方法的多次调用返回相同的Bean实例
根据
与@Configuration中bean方法的语义不同
lite模式下不支持类“bean间引用”。
相反,当一个@Bean方法调用lite中的另一个@Bean方法时
模式,调用是标准的Java方法调用;春天
不通过CGLIB代理拦截调用。这类似于
事务间方法调用,而在代理模式下,Spring不调用
拦截调用-Spring仅在AspectJ模式下执行此操作
所以观察到
Spring为注释为@Transactional和@Transactional的bean创建了代理
在@Component类内部配置
原因一如预期
@Transactional
注释的类需要代理@Component
注释的类不需要任何特殊处理@Transactional
注释@Component
注释类以解释代理@Configuration
类来解释“bean间引用”支持ConfigurationBean.init()
方法,没有解释代理的@Transactional
rg.xx.xx.TranslatorApplication$ComponentConf@8a589a2 : TranslatorApplication$ComponentConf$$EnhancerBySpringCGLIB$$e204f764
rg.xx.xx.TranslatorApplication$ComponentBean@c65a5ef : TranslatorApplication$ComponentBean$$EnhancerBySpringCGLIB$$d3d05c88
rg.xx.xx.TranslatorApplication$ComponentBean@6b5176f2 : TranslatorApplication$ComponentBean$$EnhancerBySpringCGLIB$$d3d05c88
rg.xx.xx.TranslatorApplication$ConfigurationConf$$EnhancerBySpringCGLIB$$9369a982@b672aa8 : TranslatorApplication$ConfigurationConf$$EnhancerBySpringCGLIB$$9369a982
rg.xx.xx.TranslatorApplication$ConfigurationBean@2fab4aff : ConfigurationBean
rg.xx.xx.TranslatorApplication$ConfigurationBean@2fab4aff : ConfigurationBean
请注意
ComponentConf
bean被代理ComponentBean
由于Lite模式,返回两个不同的bean实例ConfigurationBean
返回相同的实例ConfigurationBean
实例未被代理@Configuration
类的工作方面有一个很好的例子。一定要读书
希望这有帮助。我会尽力解释
若配置被注释为组件,那个么spring不会创建代理
此配置的类
Spring容器仅在需要时为bean创建代理,就像对bean的任何特殊处理一样,例如:AOP、事务管理。我已经为另一个SO问题解释了这一点,如果有兴趣,请浏览答案的A2部分
因此,例如,如果用@Transactional
注释类,那么Conf
类bean将是一个代理
此类中所有配置的bean都被视为普通方法
召唤
不对。Lite模式中的所有自调用或内部方法调用都是普通方法调用,而不是用@Configuration
注释的类中的特殊处理。在@Configuration
注释类中,对@Bean
注释方法的多次调用返回相同的Bean实例
根据
与@Configuration中bean方法的语义不同
lite模式下不支持类“bean间引用”。
相反,当一个@Bean方法调用lite中的另一个@Bean方法时
模式,调用是标准的Java方法调用;春天
不通过CGLIB代理拦截调用。这类似于
事务间方法调用,而在代理模式下,Spring不调用
拦截调用-Spring仅在AspectJ模式下执行此操作
所以观察到
Spring为注释为@Transactional和@Transactional的bean创建了代理
在@Component类内部配置
原因一如预期
@Transactional
注释的类需要代理@Component
注释的类不需要任何特殊处理@Transactional
注释@Component
注释类以解释代理@Configuration
类来解释“bean间引用”支持ConfigurationBean.init()
方法,没有解释代理的@Transactional
rg.xx.xx.TranslatorApplication$ComponentConf@8a589a2 : TranslatorApplication$ComponentConf$$EnhancerBySpringCGLIB$$e204f764
rg.xx.xx.TranslatorApplication$ComponentBean@c65a5ef : TranslatorApplication$ComponentBean$$EnhancerBySpringCGLIB$$d3d05c88
rg.xx.xx.TranslatorApplication$ComponentBean@6b5176f2 : TranslatorApplication$ComponentBean$$EnhancerBySpringCGLIB$$d3d05c88
rg.xx.xx.TranslatorApplication$ConfigurationConf$$EnhancerBySpringCGLIB$$9369a982@b672aa8 : TranslatorApplication$ConfigurationConf$$EnhancerBySpringCGLIB$$9369a982
rg.xx.xx.TranslatorApplication$ConfigurationBean@2fab4aff : ConfigurationBean
rg.xx.xx.TranslatorApplication$ConfigurationBean@2fab4aff : ConfigurationBean
请注意
ComponentConf
bean被代理ComponentBean
由于Lite模式,返回两个不同的bean实例ConfigurationBean
返回相同的实例ConfigurationBean
ar实例