SpringBoot向容器注册bean的方法详解(spring怎么注册到容器)

网友投稿 293 2022-07-30


目录简介法1:@Component法2:@Configuration+@Bean法3:@Import等法4:FactoryBean

简介

本文用示例介绍SpringBoot如何向容器注册bean(即:将对象加入容器)。

法1:@Component

(@Controller/@Service/@Repository也可以,因为它里边包含@Component)

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

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

@SpringBootApplication(scanBasePackages="com.test.chapter4")

此注解其实是@ComponentScan的basePackages,通过查看scanBasePackages即可得知。

@SpringBootApplication只会扫描@SpringBootApplication注解标记类包下及其子包的类,将这些类纳入到spring容器,只要类有@Component注解即可。

有的注解的定义中已加入@Component,所以这些注解也会被扫描到:@Controller,@Service,@Configuration,@Bean

@ComponentScan+@Configuration+@Component

DemoConfig在扫描路径之内

@Configuration

@ComponentScan(basePackages = { "com.example.demo.mybeans" })

public class DemoConfig {

}

MyBean1在com.example.demo.mybeans下

@Component

public class MyBean1{

}

法2:@Configuration+@Bean

使用场景:将没有Component等注解的类导入。例如:第三方包里面的组件、将其他jar包中的类。

public class User {

//@Value("Tom")

public String username;

public User(String s) {

this.username = s;

}

}

@Configuration

public class ImportConfig {

@Bean

public User user(){

return new User("Lily");

}

}

@RestController

public class ImportDemoConthttp://rokdZZiller {

@Autowired

private User user;

@RequestMapping("/importDemo")

public String demo() throws Exception {

String s = user.username;

return "ImportDemo@SpringBoot " + s;

}

}

法3:@Import等

简介

@Import(要导入到容器中的组件);容器会自动注册这个组件,id默认是全类名。(@http://Import是Spring的注解。)

ImportSelector:返回需要导入的组件的全类名数组;

ImportBeanDefinitionRegistrar:手动注册bean到容器中

@Import方式

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Import({ImportDemoConfig.class})

public @interface EnableImportDemo {

}

public class ImportDemoConfig{

@Bean

public User user(){

return new User("Lily");

}

}

@EnableImportDemo

@SpringBootApplication

public class DemoApplication {

public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}

@RestController

public class ImportDemoController {

@Autowired

private User user;

@RequestMapping("/importDemo")

public String demo() {

String s = user.getName();

return "user.getName():" + s;

}

}

ImportSelector方式

//自定义逻辑返回需要导入的组件

public class MyImportSelector implements ImportSelector {

//返回值,就是到导入到容器中的组件全类名

//AnnotationMetadata:当前标注@Import注解的类的所有注解信息

@Override

public String[] selectImports(AnnotationMetadata importingClassMetadata) {

//当前类的所有注解

Set annotationTypes = importingClassMetadata.getAnnotationTypes();

System.out.println("当前配置类的注解信息:"+annotationTypes);

//注意不能返回null,不然会报NullPointException

return 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 {

@Bean

public User user(){

return new User("Lily");

}

}

@RestController

public class ImportDemoController {

@Autowired

private User user;

@Autowired

private ImportDemo importDemo;

@Autowired

private 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:当前类的注解信息

* BeanDefinitionRegistry:BeanDefinition注册类;

* 把所有需要添加到容器中的bean;调用

* BeanDefinitionRegistry.registerBeanDefinition手工注册进来

*/

@Override

public 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);

//注册一个Bean,指定bean名

registry.registerBeanDefinition("User03", beanDefinition);

}

}

}

public class User03 {

public String username;

public User03() {

System.out.println("user03...constructor");

}

}

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

法4:FactoryBean

默认获取到的是工厂bean调用getObject创建的对象。

要获取工厂Bean本身,我们需要给id前面加一个&。例如:&xxxFactoryBean 注意类名是X,这里就是小写的x

public class UserFactoryBean implements FactoryBean {

@Override

public User04 getObject() throws Exception {

// TODO Auto-generated method stub

System.out.println("UserFactoryBean...getObject...");

return new User04("User04");

}

@Override

public Class> getObjectType() {

// TODO Auto-generated method stub

return User04.class;

}

//是否单例?

//true:这个bean是单实例,在容器中保存一份

//false:多实例,每次获取都会创建一个新的bean;

@Override

public boolean isSingleton() {

return 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 {

// 要获取工厂Bean本身,需要给id前面加一个&,&userFactoryBean

@Bean

public UserFactoryBean userFactoryBean(){

return new UserFactoryBean();

}

@Bean

public User user(){

return new User("Lily");

}

}

@RestController

public class ImportDemoController {

@Autowired

private User user;

@Autowired

private ImportDemo importDemo;

@Autowired

private User01 user01;

@Autowired

private 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]);

}

}

}

测试结果

以上就是SpringBoot向容器注册bean的方法详解的详细内容,更多关于SpringBoot注册bean的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot整合EasyExcel实现导入导出数据(springboot easypoi导出excel)
下一篇:详解Java中AC自动机的原理与实现(ac自动机算法)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~