1、@configuration+@bean注入组件
spring是是通过xml给容器添加组件的,在Springboot可以通过@configuration配置类的方式添加组件
@Configuration //告诉boot这是一个配置类,相当于Spring中的配置文件 public class MyConfig { /** *1、通过配置类给容器添加组件 方法名作为组件的id返回类型就是组件的类型 返回的值就是组件在容器中的实列 *2、如果不想让方法名作为组件id 可以在bean注解中传参 *3、无论对这个方法调用多少次 获取到的都是之前注册进容器中的单实例对象 * @Bean("testUser") */ @Bean public User demoUser(){ return new User("回去吧三哥",18); } }
查看容器中注入的组件
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { //返回我们的容器 ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); //2.查看容器里的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
fastJsonpResponseBodyAdvice demoUser restTemplate simpleClientHttpRequestFactory org.springframework.boot.autoconfigure.AutoConfigurationPackages org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration propertySourcesPlaceholderConfigurer
并且我们注入的组件在容器中是单例的,测试如下
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { //返回我们的容器 ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); //精确获取组件 User user1 = run.getBean("demoUser", User.class); User user2 = run.getBean("demoUser", User.class); System.out.println(user1==user2);//打印true } }
注意:配置类本身也是一个组件
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { //返回我们的容器 ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); //精确获取组件 MyConfig myConfig = run.getBean(MyConfig.class); System.out.println(myConfig); //使用 User user = myConfig.demoUser(); System.out.println(user); } } com.common.config.MyConfig$$EnhancerBySpringCGLIB$$3ef8885e@1999e1f5 com.user.User@b1fa523
boot2版本对于Configuration注解新增了一个属性proxyBeanMethods,默认是true;会使用代理对象调用组件方法,boot总会检查容器中是否有这个容器,即保持组件单实例
@Configuration(proxyBeanMethods = true) public class MyConfig { @Bean public User demoUser(){ return new User("回去吧三哥",18); } } //打印true @SpringBootApplication public class DemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); MyConfig myConfig = run.getBean(MyConfig.class); User user = myConfig.demoUser(); User user1 = myConfig.demoUser(); System.out.println(user==user1);//true } }
如果改为false
@Configuration(proxyBeanMethods = false) public class MyConfig { @Bean public User demoUser(){ return new User("回去吧三哥",18); } } //打印true @SpringBootApplication public class DemoApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); MyConfig myConfig = run.getBean(MyConfig.class); User user = myConfig.demoUser(); User user1 = myConfig.demoUser(); System.out.println(user==user1);//false } }
上面两种方式就是boot2中的底层配置的两种方式,主要用来解决组件依赖,
Full(全配置),即增加proxyBeanMethods = true;如果注册的组件在别组件会用到,那就设置为true 保证单实例;
Lite(轻量级),即增加proxyBeanMethods = false;如果注册的组件在别组件不会用到,那就设置为false 减少判断 加快启动
2、@Controller @Service @Repository @Component注入组件
除了上面的@Configuration+@bean方式给容器注入一个组件,还可使用@Controller @Service @Repository @Component结合@bean注入组件
3、另外也可用@Import注册组件,但是要放在标有
@Configuration、@Controller、 @Service、 @Repository、 @Component注解标识的类上
@Import({User.class}) @Configuration public class MyConfig { public User demoUser(){ return new User("回去吧三哥",18); } }
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { //返回我们的容器 ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args); String[] beans = run.getBeanNamesForType(User.class); for (String name : beans) { System.out.println(name);//com.user.User } } }
4、根据条件注册组件
案例一:用在方法上
@Configuration public class MyConfig { @ConditionalOnBean(name = "tom")//只有容器中有tom这个组件,才会注入demoUser组件 @Bean public User demoUser(){ return new User("回去吧三哥",18); } }
案例二:用在类上
@Configuration @ConditionalOnBean(name = "tom")//只有容器中有tom这个组件,才会注入demoUser组件和testUser组件 public class MyConfig { @Bean public User demoUser(){ return new User("回去吧三哥",18); } @Bean public User testUser(){ return new User("回去吧三哥",18); } }