曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 (2)

org.springframework.simple.TestService#0,这和我们平时使用autowired方式,生成的beanName不一样啊,不习惯。于是改成了org.springframework.context.annotation.AnnotationBeanNameGenerator,就对了!

如何表达bean间依赖

这里先介绍两种方式,分别是构造器注入和property注入。对了,先不要和我提什么autowired哈,那个是自动,这个呢,手动。也许,后面你会更懂autowired,也更懂自动。

构造器注入

核心代码:

@ToString public class TestControllerByConstructor { TestService testService; /** * 基本类型依赖 */ private String name; public TestControllerByConstructor(TestService testService, String name) { this.testService = testService; this.name = name; } public TestService getTestService() { return testService; } public String getName() { return name; } } package org.springframework.simple; import lombok.ToString; @ToString public class TestService implements ITestService{ } /** * 2. 构造bean definition,并在bean definition中表达bean之间的依赖关系 */ GenericBeanDefinition iTestServiceBeanDefinition = (GenericBeanDefinition) BeanDefinitionBuilder .genericBeanDefinition(TestService.class).getBeanDefinition(); log.info("iTestServiceBeanDefinition:{}",iTestServiceBeanDefinition); GenericBeanDefinition iTestControllerBeanDefinition = (GenericBeanDefinition) BeanDefinitionBuilder .genericBeanDefinition(TestControllerByConstructor.class) // 这里,看这里,这里在表达依赖了 .addConstructorArgReference("testService") .addConstructorArgValue("wire by constructor") .getBeanDefinition();

完整代码:

package org.springframework.simple.byconstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.support.*; import org.springframework.context.annotation.AnnotationBeanNameGenerator; import org.springframework.simple.ITestService; import org.springframework.simple.TestService; import org.springframework.util.Assert; @Slf4j public class ManualRegisterBeanDefinitionDemoByConstructor { public static void main(String[] args) { wireDependencyByConstructor(); } /** * 通过构造器的方式来注入依赖 */ private static void wireDependencyByConstructor() { /** * 1:生成bean factory */ DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); /** * 2. 构造bean definition,并在bean definition中表达bean之间的依赖关系 */ GenericBeanDefinition iTestServiceBeanDefinition = (GenericBeanDefinition) BeanDefinitionBuilder .genericBeanDefinition(TestService.class).getBeanDefinition(); log.info("iTestServiceBeanDefinition:{}",iTestServiceBeanDefinition); GenericBeanDefinition iTestControllerBeanDefinition = (GenericBeanDefinition) BeanDefinitionBuilder .genericBeanDefinition(TestControllerByConstructor.class) .addConstructorArgReference("testService") .addConstructorArgValue("wire by constructor") .getBeanDefinition(); /** * 3. 注册bean definition */ // DefaultBeanNameGenerator generator = new DefaultBeanNameGenerator(); AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator(); String beanNameForTestService = generator.generateBeanName(iTestServiceBeanDefinition, factory); factory.registerBeanDefinition(beanNameForTestService, iTestServiceBeanDefinition); String beanNameForTestController = generator.generateBeanName(iTestControllerBeanDefinition, factory); factory.registerBeanDefinition(beanNameForTestController, TestControllerBeanDefinition); /** * 4. 获取bean */ TestControllerByConstructor bean = factory.getBean(TestControllerByConstructor.class); log.info("TestControllerByConstructor:{}",bean); ITestService testService = factory.getBean(ITestService.class); log.info("testService bean:{}",testService); Assert.isTrue(bean.getTestService() == testService); } } property注入

原理类似,核心代码不同之处如下:

GenericBeanDefinition iTestControllerBeanDefinition = (GenericBeanDefinition) BeanDefinitionBuilder .genericBeanDefinition(TestControllerWireByProperty.class) // 这里是调用的property相关方法 .addPropertyReference("t","testService") .addPropertyValue("name","just test") .getBeanDefinition(); 总结

今天就到这里,有问题请指出哈,欢迎大家和我一起阅读spring boot源码

源码地址:

https://gitee.com/ckl111/spring-boot-first-version-learn/tree/master/all-demo-in-spring-learning/spring-manual-register-bean-definition

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpssfx.html