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