javascript
Spring-几种组件注册方式
Spring-幾種組件注冊方式
happybean
一只不正經的程序猿。。。
IOC(Inversion of Control)控制反轉,spring中的核心,有了ioc容器,在程序開發過程中可以將bean對象托管給Spring容器進行管理(管理對象的生命周期,對象之間的依賴關系等),從而更好的專注于業務開發,減少代碼工作量。
下面介紹幾種組件注冊到容器中的方式
!注意以下Spring版本不同,實現方式可能會到受影響
1.配置文件注冊方式
引入spring-context maven依賴
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.17.RELEASE</version> </dependency>bean測試類
public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';} }創建spring-bean.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--基于配置方式 id,name 要保證唯一性--><bean class="org.happybean.bean.Person" name="person1" id="person1-id" ><property name="name" value="spring1"/><property name="age" value="20"/></bean><bean class="org.happybean.bean.Person" name="person2" id="person2-id" ><property name="name" value="spring2"/><property name="age" value="21"/></bean> </beans>測試使用
public static void main(String[] args) {//加載配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");//根據 bean name 獲取,需要類型強制轉換Person person1 = (Person) applicationContext.getBean("person1");System.out.println("person1:"+person1);//根據bean id 獲取,需要類型強制轉換Person person2 = (Person) applicationContext.getBean("person2-id");System.out.println("person2:"+person2);//根據bean類型獲取,無需要類型強制轉換,//使用此種方式時要保證改類型bean只配置一個,否則會拋出異常 org.springframework.beans.factory.NoUniqueBeanDefinitionExceptionPerson person3 = applicationContext.getBean(Person.class);System.out.println("person3:"+person3);//根據bean name和類型獲取,無需要類型強制轉換//多個相同類型bean時,可以使用該方法獲取Person person4 = applicationContext.getBean("person1", Person.class);System.out.println("person4:"+person4); }2.配置類注冊方式
配置類
@Configuration public class SpringConfig {//@Configuration 告訴spring這是一個配置類@Beanpublic Person person1(){//@Bean 將對象注冊到容器 name默認為方法名return new Person("spring1",20);}@Bean(name = "person2-name")public Person person2(){//@Bean 將對象注冊到容器 id默認為方法名return new Person("spring2",21);} }測試使用
public static void main(String[] args) {//加載配置類 此時的配置類等同于xml配置文件ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);//根據bean 默認name(方法名) 獲取,需要類型強制轉換Person person1 = (Person) applicationContext.getBean("person1");System.out.println("person1:" + person1);//根據 bean name 獲取,需要類型強制轉換Person person2 = (Person) applicationContext.getBean("person2-name");System.out.println("person2:" + person2);//根據bean name和類型獲取,無需要類型強制轉換//多個相同類型bean時,可以使用該方法獲取Person person4 = applicationContext.getBean("person1", Person.class);System.out.println("person4:" + person4);//獲取bean 在容器中的 nameString[] beanNames = applicationContext.getBeanDefinitionNames();for (String name : beanNames) {System.out.println(name);} }3.Xml配置文件包掃描方式
配置文件 spring-scan.xml
<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 http://www.springframework.org/schema/context/spring-context.xsd"><!--配置文件方式掃描,@Controller @Service @Repository等注解的類會以bean方式注冊到容器中--><context:component-scan base-package="org.happybean.controller,org.happybean.service,org.happybean.repository"/> </beans>注冊bean時默認使用單例模式注入,或者可以在bean標簽中定義?scope="prototype"定義為多實例模式
4.配置類注解包掃描方式
配置類
@Configuration @ComponentScan(value = {"org.happybean.controller", "org.happybean.service", "org.happybean.repository"}) public class SpringConfig { }包掃描方式會默認以類首字母小寫作為?bean name,或者也可以用@Controller("SpringController")方式自定義name
當然你也可以使用?@ComponentScan中的excludeFilters排除不需要注冊到容器中的類
或用以下配置類方式實現多實例模式
@Bean @Scope("prototype") public Person person1() {return new Person("spring1", 20); }通過測試我們可以得知,在使用默認的單例模式注冊時,spring會使用餓漢模式進行注冊,如果想改為懶加載模式(懶漢模式),可以在xml配置文件bean標簽中加入lazy-init="true”,或者以如下方式實現
@Lazy @Bean(name = "person2-name") public Person person2() {//@Bean 將對象注冊到容器 id默認為方法名//使用@Lazy將單例模式下的bean改為懶加載模式(懶漢模式)return new Person("spring2", 21); }5.條件注冊方式
如果你想滿足某種條件下才注冊bean,可以使用如下方式
創建一個注冊條件類 必須實現?org.springframework.context.annotation.Condition
public class OsCondition implements Condition {/*** 滿足操作系統是mac時才會創建 name為喬布斯的bean** @param conditionContext 上下文(環境)* @param annotatedTypeMetadata 注解信息*/@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {//獲取環境信息Environment environment = conditionContext.getEnvironment();//獲取操作系統信息String osName = environment.getProperty("os.name");if (osName.equals("Mac OS X")) {return true;}return false;} }bean配置
@Bean @Conditional(OsCondition.class) public Person steveJobs() {//@Conditional 滿足某種條件下才會注冊beanreturn new Person("steveJobs", 56); }測試使用
public static void main(String[] args) {//加載配置類 此時的配置類等同于xml配置文件ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);//獲取bean 在容器中的 nameString[] beanNames = applicationContext.getBeanDefinitionNames();for (String name : beanNames) {System.out.println(name);} }這種方式在springboot中也大量的使用
6.手動注冊方式
也許你還想自己手動注冊一個bean,可以嘗試如下寫法
public static void main(String[] args) {//加載配置類 此時的配置類等同于xml配置文件ApplicationContext applicationContext = new AnnotationConfigApplicationContext();//獲取bean工廠ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) applicationContext;BeanDefinitionRegistry registry = (DefaultListableBeanFactory) configurableContext.getBeanFactory();//bean builderBeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Person.class);BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();//手動注冊beanregistry.registerBeanDefinition("manual", beanDefinition);//獲取bean 在容器中的 nameString[] beanNames = applicationContext.getBeanDefinitionNames();for (String name : beanNames) {System.out.println(name);} }?
7.快速注冊方式
如果你想快速將一個類注冊到容器中,可以使用@Import
bean?默認name是類全名 例如:org.happybean.bean.Person
@Configuration @Import({Person.class}) public class SpringConfig { }@Import中可以寫多個class
8.批量注冊方式
可以在@Import注解中添加一個ImportSelector類以實現批量注冊的功能
自定義注冊選擇器
public class SpringImportSelector implements ImportSelector {/*** 注冊的所有類** @param annotationMetadata 當前類注解的信息 例如:@Import* @return 所有需要注冊到容器的全類名*/@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {String[] className = {"org.happybean.bean.Animal"};return className;} }配置類
@Configuration @Import(SpringImportSelector.class) public class SpringConfig { }9.@Import注解 手動注冊方式
此時你需要編寫一個org.springframework.context.annotation.ImportBeanDefinitionRegistrar
實現類
public class SpringImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** @param annotationMetadata 當前類注解信息* @param beanDefinitionRegistry beanDefinition 注冊類*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {//判斷是否存在 name為animal 的beanif (!beanDefinitionRegistry.containsBeanDefinition("animal")) {BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Animal.class);BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();beanDefinitionRegistry.registerBeanDefinition("animal", beanDefinition);}} }使用方式同上
@Configuration @Import(SpringImportBeanDefinitionRegistrar.class) public class SpringConfig { }轉載于:https://my.oschina.net/u/3439484/blog/3023014
總結
以上是生活随笔為你收集整理的Spring-几种组件注册方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金蝶EAS解决方案
- 下一篇: gradle idea java ssm