小言_互联网的博客

Spring Bean四种注入方式(Springboot环境)

319人阅读  评论(0)

阅读此文建议参考本人写的Spring常用注解:https://blog.csdn.net/21aspnet/article/details/104042826

给容器中注册组件的四种方法:


 1.@ComponentScan包扫描+组件标注注解@Component(@Controller@Service@Repository)
使用场景:自己写的代码,可以方便的加@Controller/@Service/@Repository/@Component


  
  1. @SpringBootApplication
  2. 源码
  3. @Target(ElementType.TYPE)
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Documented
  6. @Inherited
  7. @SpringBootConfiguration
  8. @EnableAutoConfiguration
  9. @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  10. @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  11. public @interface SpringBootApplication

默认是加载和Application类所在同一个目录下的所有类,包括所有子目录下的类。

当启动类和@Component分开时,如果启动类在某个包下,需要在启动类中增加注解@ComponentScan,配置需要扫描的包名。


2.@Configuration+@Bean   
使用场景:导入的第三方包里面的组件,将其他jar包中的类(类没有Component等注解),加载到容器中。


  
  1. public class User {
  2. //@Value("Tom")
  3. public String username;
  4. public User(String s) {
  5. this.username = s;
  6. }
  7. }
  8. @Configuration
  9. public class ImportConfig {
  10. @Bean
  11. public User user(){
  12. return new User( "Lily");
  13. }
  14. }
  15. @RestController
  16. public class ImportDemoController {
  17. @Autowired
  18. private User user;
  19. @RequestMapping( "/importDemo")
  20. public String demo() throws Exception {
  21. String s = user.username;
  22. return "ImportDemo@SpringBoot " + s;
  23. }
  24. }


3.@Import快速给容器中导入一个组件
         1)@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
         2)ImportSelector:返回需要导入的组件的全类名数组;
         3)ImportBeanDefinitionRegistrar:手动注册bean到容器中

 

@Import方式


  
  1. public class ImportDemo {
  2. public void doSomething () {
  3. System.out.println( "ImportDemo.doSomething()");
  4. }
  5. }
  6. @Configuration
  7. @Import({ImportDemo.class})
  8. public class ImportConfig{
  9. @Bean
  10. public User user(){
  11. return new User( "Lily");
  12. }
  13. }
  14. @RestController
  15. public class ImportDemoController {
  16. @Autowired
  17. private User user;
  18. @Autowired
  19. private ImportDemo importDemo;
  20. @RequestMapping( "/importDemo")
  21. public String demo() throws Exception {
  22. importDemo.doSomething();
  23. String s = user.username;
  24. return "ImportDemo@SpringBoot " + s;
  25. }
  26. }

ImportSelector方式


  
  1. //自定义逻辑返回需要导入的组件
  2. public class MyImportSelector implements ImportSelector {
  3. //返回值,就是到导入到容器中的组件全类名
  4. //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
  5. @Override
  6. public String[] selectImports(AnnotationMetadata importingClassMetadata) {
  7. // TODO Auto-generated method stub
  8. //importingClassMetadata
  9. //方法不要返回null值
  10. //当前类的所有注解
  11. Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();
  12. System.out.println( "当前配置类的注解信息:"+annotationTypes);
  13. //注意不能返回null,不然会报NullPointException
  14. return new String[]{ "com.paopaoedu.springboot.bean.user01", "com.paopaoedu.springboot.bean.user02"};
  15. }
  16. }
  17. public class User01 {
  18. public String username;
  19. public User01() {
  20. System.out.println( "user01...constructor");
  21. }
  22. }
  23. public class User02 {
  24. public String username;
  25. public User02() {
  26. System.out.println( "user02...constructor");
  27. }
  28. }
  29. @Configuration
  30. @Import({ImportDemo.class, MyImportSelector.class})
  31. public class ImportConfig {
  32. /**
  33. * 给容器中注册组件;
  34. * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
  35. * 2)、@Bean[导入的第三方包里面的组件]
  36. * 3)、@Import[快速给容器中导入一个组件]
  37. * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
  38. * 2)、ImportSelector:返回需要导入的组件的全类名数组;
  39. * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
  40. * 4)、使用Spring提供的 FactoryBean(工厂Bean);
  41. * 1)、默认获取到的是工厂bean调用getObject创建的对象
  42. * 2)、要获取工厂Bean本身,我们需要给id前面加一个&,&userFactoryBean
  43. */
  44. @Bean
  45. public User user(){
  46. return new User( "Lily");
  47. }
  48. }
  49. @RestController
  50. public class ImportDemoController {
  51. @Autowired
  52. private User user;
  53. @Autowired
  54. private ImportDemo importDemo;
  55. @Autowired
  56. private User01 user01;
  57. @RequestMapping( "/importDemo")
  58. public String demo() throws Exception {
  59. importDemo.doSomething();
  60. user01.username = "user01";
  61. String s = user.username;
  62. String s1 = user01.username;
  63. return "ImportDemo@SpringBoot " + s + " " + s1;
  64. }
  65. }

ImportBeanDefinitionRegistrar方式


  
  1. public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
  2. /**
  3. * AnnotationMetadata:当前类的注解信息
  4. * BeanDefinitionRegistry:BeanDefinition注册类;
  5. * 把所有需要添加到容器中的bean;调用
  6. * BeanDefinitionRegistry.registerBeanDefinition手工注册进来
  7. */
  8. @Override
  9. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  10. boolean definition = registry.containsBeanDefinition( "com.paopaoedu.springboot.bean.User01");
  11. boolean definition2 = registry.containsBeanDefinition( "com.paopaoedu.springboot.bean.User02");
  12. if(definition && definition2){
  13. //指定Bean定义信息作用域都可以在这里定义;(Bean的类型,Bean。。。)
  14. RootBeanDefinition beanDefinition = new RootBeanDefinition(User03.class);
  15. //注册一个Bean,指定bean名
  16. registry.registerBeanDefinition( "User03", beanDefinition);
  17. }
  18. }
  19. }

  
  1. public class User03 {
  2. public String username;
  3. public User03() {
  4. System.out.println( "user03...constructor");
  5. }
  6. }

 使用上和前面的类似就不举例了。


4.使用Spring提供的 FactoryBean(工厂Bean)
         1)默认获取到的是工厂bean调用getObject创建的对象
         2)要获取工厂Bean本身,我们需要给id前面加一个&
            &xxxFactoryBean 注意类名是X,这里就是小写的x?


  
  1. public class UserFactoryBean implements FactoryBean<User04> {
  2. @Override
  3. public User04 getObject() throws Exception {
  4. // TODO Auto-generated method stub
  5. System.out.println( "UserFactoryBean...getObject...");
  6. return new User04( "User04");
  7. }
  8. @Override
  9. public Class<?> getObjectType() {
  10. // TODO Auto-generated method stub
  11. return User04.class;
  12. }
  13. //是否单例?
  14. //true:这个bean是单实例,在容器中保存一份
  15. //false:多实例,每次获取都会创建一个新的bean;
  16. @Override
  17. public boolean isSingleton() {
  18. // TODO Auto-generated method stub
  19. return true;
  20. }
  21. }
  22. public class User04 {
  23. public String username;
  24. public User04(String s) {
  25. String nowtime= DateUtil.now();
  26. username=s+ " "+nowtime;
  27. }
  28. }
  29. @Configuration
  30. @Import({ImportDemo.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
  31. public class ImportConfig {
  32. /**
  33. * 给容器中注册组件;
  34. * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
  35. * 2)、@Bean[导入的第三方包里面的组件]
  36. * 3)、@Import[快速给容器中导入一个组件]
  37. * 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
  38. * 2)、ImportSelector:返回需要导入的组件的全类名数组;
  39. * 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
  40. * 4)、使用Spring提供的 FactoryBean(工厂Bean);
  41. * 1)、默认获取到的是工厂bean调用getObject创建的对象
  42. * 2)、要获取工厂Bean本身,我们需要给id前面加一个&,&userFactoryBean
  43. */
  44. @Bean
  45. public UserFactoryBean userFactoryBean(){
  46. return new UserFactoryBean();
  47. }
  48. @Bean
  49. public User user(){
  50. return new User( "Lily");
  51. }
  52. }
  53. @RestController
  54. public class ImportDemoController {
  55. @Autowired
  56. private User user;
  57. @Autowired
  58. private ImportDemo importDemo;
  59. @Autowired
  60. private User01 user01;
  61. @Autowired
  62. private UserFactoryBean userFactoryBean;
  63. @RequestMapping( "/importDemo")
  64. public String demo() throws Exception {
  65. importDemo.doSomething();
  66. user01.username = "user01";
  67. String s = user.username;
  68. String s1 = user01.username;
  69. String s4 = userFactoryBean.getObject().username;
  70. return "ImportDemo@SpringBoot " + s + " " + s1 + " " + s4;
  71. }
  72. }
  73. @SpringBootApplication
  74. public class SpringBootLearningApplication {
  75. public static void main(String[] args) {
  76. SpringApplication.run(SpringBootLearningApplication.class, args);
  77. AnnotationConfigApplicationContext context =
  78. new AnnotationConfigApplicationContext( "com.paopaoedu.springboot.config");
  79. ImportDemo importDemo = context.getBean(ImportDemo.class);
  80. importDemo.doSomething();
  81. printClassName(context);
  82. Object bean1 = context.getBean( "userFactoryBean");
  83. Object bean2 = context.getBean( "userFactoryBean");
  84. System.out.println(bean1 == bean2);
  85. }
  86. private static void printClassName(AnnotationConfigApplicationContext annotationConfigApplicationContext){
  87. String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
  88. for ( int i = 0; i < beanDefinitionNames.length; i++) {
  89. System.out.println( "匹配的类"+beanDefinitionNames[i]);
  90. }
  91. }
  92. }

 

 

如果基础不够可以再看看此文: 

https://blog.csdn.net/qq_27470131/category_7502799.html 


转载:https://blog.csdn.net/21aspnet/article/details/104239784
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场