Spring Bean四种注入方式(Springboot环境)
閱讀此文建議參考本人寫的Spring常用注解:https://blog.csdn.net/21aspnet/article/details/104042826
給容器中注冊(cè)組件的四種方法:
?1.@ComponentScan包掃描+組件標(biāo)注注解@Component(@Controller@Service@Repository)
使用場(chǎng)景:自己寫的代碼,可以方便的加@Controller/@Service/@Repository/@Component
@SpringBootApplication
源碼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication
默認(rèn)是加載和Application類所在同一個(gè)目錄下的所有類,包括所有子目錄下的類。
當(dāng)啟動(dòng)類和@Component分開時(shí),如果啟動(dòng)類在某個(gè)包下,需要在啟動(dòng)類中增加注解@ComponentScan,配置需要掃描的包名。
2.@Configuration+@Bean ??
使用場(chǎng)景:導(dǎo)入的第三方包里面的組件,將其他jar包中的類(類沒有Component等注解),加載到容器中。
public class User {//@Value("Tom")public String username;public User(String s) {this.username = s;}
}@Configuration
public class ImportConfig {@Beanpublic User user(){return new User("Lily");}
}@RestController
public class ImportDemoController {@Autowiredprivate User user;@RequestMapping("/importDemo")public String demo() throws Exception {String s = user.username;return "ImportDemo@SpringBoot " + s;}
}
3.@Import快速給容器中導(dǎo)入一個(gè)組件
?????????1)@Import(要導(dǎo)入到容器中的組件);容器中就會(huì)自動(dòng)注冊(cè)這個(gè)組件,id默認(rèn)是全類名
?????????2)ImportSelector:返回需要導(dǎo)入的組件的全類名數(shù)組;
?????????3)ImportBeanDefinitionRegistrar:手動(dòng)注冊(cè)bean到容器中
?
@Import方式
public class ImportDemo {public void doSomething () {System.out.println("ImportDemo.doSomething()");}
}@Configuration
@Import({ImportDemo.class})
public class ImportConfig{
@Beanpublic User user(){return new User("Lily");}
}@RestController
public class ImportDemoController {@Autowiredprivate User user;@Autowiredprivate ImportDemo importDemo;@RequestMapping("/importDemo")public String demo() throws Exception {importDemo.doSomething();String s = user.username;return "ImportDemo@SpringBoot " + s;}
}
ImportSelector方式
//自定義邏輯返回需要導(dǎo)入的組件
public class MyImportSelector implements ImportSelector {//返回值,就是到導(dǎo)入到容器中的組件全類名//AnnotationMetadata:當(dāng)前標(biāo)注@Import注解的類的所有注解信息@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// TODO Auto-generated method stub//importingClassMetadata//方法不要返回null值//當(dāng)前類的所有注解Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();System.out.println("當(dāng)前配置類的注解信息:"+annotationTypes);//注意不能返回null,不然會(huì)報(bào)NullPointExceptionreturn new String[]{"com.paopaoedu.springboot.bean.user01","com.paopaoedu.springboot.bean.user02"};}
}public class User01 {public String username;public User01() {System.out.println("user01...constructor");}
}public class User02 {public String username;public User02() {System.out.println("user02...constructor");}
}@Configuration
@Import({ImportDemo.class, MyImportSelector.class})
public class ImportConfig {/*** 給容器中注冊(cè)組件;* 1)、包掃描+組件標(biāo)注注解(@Controller/@Service/@Repository/@Component)[自己寫的類]* 2)、@Bean[導(dǎo)入的第三方包里面的組件]* 3)、@Import[快速給容器中導(dǎo)入一個(gè)組件]* 1)、@Import(要導(dǎo)入到容器中的組件);容器中就會(huì)自動(dòng)注冊(cè)這個(gè)組件,id默認(rèn)是全類名* 2)、ImportSelector:返回需要導(dǎo)入的組件的全類名數(shù)組;* 3)、ImportBeanDefinitionRegistrar:手動(dòng)注冊(cè)bean到容器中* 4)、使用Spring提供的 FactoryBean(工廠Bean);* 1)、默認(rèn)獲取到的是工廠bean調(diào)用getObject創(chuàng)建的對(duì)象* 2)、要獲取工廠Bean本身,我們需要給id前面加一個(gè)&,&userFactoryBean*/@Beanpublic User user(){return new User("Lily");}
}@RestController
public class ImportDemoController {@Autowiredprivate User user;@Autowiredprivate ImportDemo importDemo;@Autowiredprivate User01 user01;@RequestMapping("/importDemo")public String demo() throws Exception {importDemo.doSomething();user01.username = "user01";String s = user.username;String s1 = user01.username;return "ImportDemo@SpringBoot " + s + " " + s1;}
}
ImportBeanDefinitionRegistrar方式
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata:當(dāng)前類的注解信息* BeanDefinitionRegistry:BeanDefinition注冊(cè)類;* 把所有需要添加到容器中的bean;調(diào)用* BeanDefinitionRegistry.registerBeanDefinition手工注冊(cè)進(jìn)來*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean definition = registry.containsBeanDefinition("com.paopaoedu.springboot.bean.User01");boolean definition2 = registry.containsBeanDefinition("com.paopaoedu.springboot.bean.User02");if(definition && definition2){//指定Bean定義信息作用域都可以在這里定義;(Bean的類型,Bean。。。)RootBeanDefinition beanDefinition = new RootBeanDefinition(User03.class);//注冊(cè)一個(gè)Bean,指定bean名registry.registerBeanDefinition("User03", beanDefinition);}}}
public class User03 {public String username;public User03() {System.out.println("user03...constructor");}
}
?使用上和前面的類似就不舉例了。
4.使用Spring提供的 FactoryBean(工廠Bean)
?????????1)默認(rèn)獲取到的是工廠bean調(diào)用getObject創(chuàng)建的對(duì)象
?????????2)要獲取工廠Bean本身,我們需要給id前面加一個(gè)&
????????????&xxxFactoryBean 注意類名是X,這里就是小寫的x?
public class UserFactoryBean implements FactoryBean<User04> {@Overridepublic User04 getObject() throws Exception {// TODO Auto-generated method stubSystem.out.println("UserFactoryBean...getObject...");return new User04("User04");}@Overridepublic Class<?> getObjectType() {// TODO Auto-generated method stubreturn User04.class;}//是否單例?//true:這個(gè)bean是單實(shí)例,在容器中保存一份//false:多實(shí)例,每次獲取都會(huì)創(chuàng)建一個(gè)新的bean;@Overridepublic boolean isSingleton() {// TODO Auto-generated method stubreturn true;}
}public class User04 {public String username;public User04(String s) {String nowtime= DateUtil.now();username=s+" "+nowtime;}
}@Configuration
@Import({ImportDemo.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class ImportConfig {/*** 給容器中注冊(cè)組件;* 1)、包掃描+組件標(biāo)注注解(@Controller/@Service/@Repository/@Component)[自己寫的類]* 2)、@Bean[導(dǎo)入的第三方包里面的組件]* 3)、@Import[快速給容器中導(dǎo)入一個(gè)組件]* 1)、@Import(要導(dǎo)入到容器中的組件);容器中就會(huì)自動(dòng)注冊(cè)這個(gè)組件,id默認(rèn)是全類名* 2)、ImportSelector:返回需要導(dǎo)入的組件的全類名數(shù)組;* 3)、ImportBeanDefinitionRegistrar:手動(dòng)注冊(cè)bean到容器中* 4)、使用Spring提供的 FactoryBean(工廠Bean);* 1)、默認(rèn)獲取到的是工廠bean調(diào)用getObject創(chuàng)建的對(duì)象* 2)、要獲取工廠Bean本身,我們需要給id前面加一個(gè)&,&userFactoryBean*/@Beanpublic UserFactoryBean userFactoryBean(){return new UserFactoryBean();}@Beanpublic User user(){return new User("Lily");}
}@RestController
public class ImportDemoController {@Autowiredprivate User user;@Autowiredprivate ImportDemo importDemo;@Autowiredprivate User01 user01;@Autowiredprivate UserFactoryBean userFactoryBean;@RequestMapping("/importDemo")public String demo() throws Exception {importDemo.doSomething();user01.username = "user01";String s = user.username;String s1 = user01.username;String s4 = userFactoryBean.getObject().username;return "ImportDemo@SpringBoot " + s + " " + s1 + " " + s4;}
}@SpringBootApplication
public class SpringBootLearningApplication {public static void main(String[] args) {SpringApplication.run(SpringBootLearningApplication.class, args);AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext("com.paopaoedu.springboot.config");ImportDemo importDemo = context.getBean(ImportDemo.class);importDemo.doSomething();printClassName(context);Object bean1 = context.getBean("userFactoryBean");Object bean2 = context.getBean("userFactoryBean");System.out.println(bean1 == bean2);}private static void printClassName(AnnotationConfigApplicationContext annotationConfigApplicationContext){String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();for (int i = 0; i < beanDefinitionNames.length; i++) {System.out.println("匹配的類"+beanDefinitionNames[i]);}}
}
?
?
如果基礎(chǔ)不夠可以再看看此文:?
https://blog.csdn.net/qq_27470131/category_7502799.html?
總結(jié)
以上是生活随笔為你收集整理的Spring Bean四种注入方式(Springboot环境)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电影国歌中主要演的是啥
- 下一篇: springboot集成logback日