本篇内容介绍了“SpringBoot怎么从容器中获取对象”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
有时候在项目中,我们会自己创建一些类,类中需要使用到容器中的一些类。方法是新建类并实现ApplicationContextAware 接口,在类中建立静态对象 ApplicationContext 对象,这个对象就如同xml配置中的 applicationContext.xml,容器中类都可以获取到。
例如@Service、 @Component、@Repository、@Controller 、@Bean 标注的类都能获取到。
/** * 功能描述:Spring Bean 管理类 * */ @Component public class SpringContextUtils implements ApplicationContextAware { /** * 上下文对象实例 */ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * 获取applicationContext * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 通过name获取 Bean. * * @param name * @return */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } /** * 通过class获取Bean. * * @param clazz * @param <T> * @return */ public static <T> T getBean(Class<T> clazz) { try{ return getApplicationContext().getBean(clazz); }catch (Exception e){ return null; } } /** * 通过name,以及Clazz返回指定的Bean * * @param name * @param clazz * @param <T> * @return */ public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
(1)主要注解
@Configuration
告诉SpringBoot这是一个配置类 == 配置文件
注意:spring5.2以后@Configuration多了一个属性proxyBeanMethods,默认为true
@Configuration(proxyBeanMethods = true)
proxyBeanMethods
:代理bean的方法
Full(proxyBeanMethods = true)
、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】 外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
Lite(proxyBeanMethods = false)
【每个@Bean方法被调用多少次返回的组件都是新创建的】
组件依赖必须使用Full模式默认。其他默认是否Lite模式
● Full模式与Lite模式
○ 最佳实战
■ 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
■ 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
@Bean
给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
配置类里面使用@Bean标注在方法上给容器注册组件,默认是单实例的
配置类本身也是组件
(2) 基本使用
bean包:
Pet类:
/** * 宠物 */ public class Pet { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Pet(String name) { this.name = name; } public Pet() { } @Override public String toString() { return "Pet{" + "name='" + name + '\'' + '}'; } }
User类:
/* 用户 */ public class User { private String name; private Integer age; public User() { } public User(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
config包:
MyConfig类
@Configuration(proxyBeanMethods = false)//告诉Spring这是一个配置类 public class MyConfig { @Bean//给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例 public User user01(){ return new User("zhangsan",18); } @Bean("tom") public Pet tomcatPet(){ return new Pet("tomcat"); } }
controller包:
MainApplication类
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan("com") public class MainApplication { public static void main(String[] args) { //1、返回我们IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //3、从容器中获取组件 MyConfig bean = run.getBean(MyConfig.class); System.out.println(bean); //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。 //保持组件单实例 User user = bean.user01(); User user1 = bean.user01(); System.out.println("组件为:"+(user == user1)); } }
结果
(3)补充 @Import
给容器导入一个组件
必须写在容器中的组件上
* @Import({User.class, DBHelper.class}) * 给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名 * * * */ @Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件 public class MyConfig { }
@Configuration测试代码如下
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan("com") public class MainApplication { public static void main(String[] args) { //1、返回我们IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //3、从容器中获取组件 MyConfig bean = run.getBean(MyConfig.class); System.out.println(bean); //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。 //保持组件单实例 User user = bean.user01(); User user1 = bean.user01(); System.out.println("组件为:"+(user == user1)); //5、获取组件 String[] beanNamesForType = run.getBeanNamesForType(User.class); System.out.println("======"); for (String s : beanNamesForType) { System.out.println(s); } DBHelper bean1 = run.getBean(DBHelper.class); System.out.println(bean1); } }
@Conditional
条件装配:满足Conditional指定的条件,则进行组件注入
ConditionalOnBean
:当容器中存在指定的bean组件时才干某些事情
ConditionalOnMissingBean
:当容器中不存在指定的bean组件时才干某些事情
ConditionalOnClass
:当容器中有某个类时才干某些事情
ConditionalOnResource
:当项目的类路径存在某个资源时,才干什么事
=====================测试条件装配========================== @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件 //@ConditionalOnBean(name = "tom") @ConditionalOnMissingBean(name = "tom") public class MyConfig { @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例 public User user01(){ User zhangsan = new User("zhangsan", 18); //user组件依赖了Pet组件 zhangsan.setPet(tomcatPet()); return zhangsan; } @Bean("tom22") public Pet tomcatPet(){ return new Pet("tomcat"); } }
测试:
public static void main(String[] args) { //1、返回我们IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } boolean tom = run.containsBean("tom"); System.out.println("容器中Tom组件:"+tom); boolean user01 = run.containsBean("user01"); System.out.println("容器中user01组件:"+user01); boolean tom22 = run.containsBean("tom22"); System.out.println("容器中tom22组件:"+tom22); }
@ImportResource
导入资源
@ImportResource("classpath:beans.xml")//导入spring的配置文件 @Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = false)//告诉Spring这是一个配置类 @ConditionalOnMissingBean(name = "tom") public class MyConfig {
======================beans.xml========================= <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean id="haha" class="com.atguigu.boot.bean.User"> <property name="name" value="zhangsan"></property> <property name="age" value="18"></property> </bean> <bean id="hehe" class="com.atguigu.boot.bean.Pet"> <property name="name" value="tomcat"></property> </bean> </beans>
测试
======================测试================= boolean haha = run.containsBean("haha"); boolean hehe = run.containsBean("hehe"); System.out.println("haha:"+haha);//true System.out.println("hehe:"+hehe);//true
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;
(1) @Component + @ConfigurationProperties
properties文件
/** * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能 */ @Component @ConfigurationProperties(prefix = "mycar") public class Car { private String brand; private Integer price; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } @Override public String toString() { return "Car{" + "brand='" + brand + '\'' + ", price=" + price + '}'; } }
(2) @EnableConfigurationProperties + @ConfigurationProperties
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件 @ConditionalOnMissingBean(name = "tom") @ImportResource("classpath:beans.xml") //@EnableConfigurationProperties(Car.class) //1、开启Car配置绑定功能 //2、把这个Car这个组件自动注册到容器中 public class MyConfig {
“SpringBoot怎么从容器中获取对象”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。