面試官:Springbean的幾種注入方式都瞭解嗎?

面試官:Springbean的幾種注入方式都瞭解嗎?

Spring注入方式可以分為三類,xml注入、註解注入、BeanDefinition注入;用法上可以分為三種,但是底層實現代碼都是統一BeanFactory,這三種也有聯繫xml注入和annotation注入都是依賴BeanDefinition擴展的接口,註解也是從xml過渡過來的,我們簡單的看下這三種的寫法。

XML注入

在springboot框架沒有出來之前,xml配置被大量的使用,配置過程比較繁瑣,但是對代碼的侵入性較小,配置和代碼分離操作。

實體定義

定義兩個屬性id,name,並實現get/set方法,重寫toString方法,方便看打印結果。

<code>public class UserXml {
private String id;
private String name;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override

public String toString() {
return "User{"
"id='" id '\\''
", name='" name '\\''
'}';
}
}/<code>

xml定義

在resources下新建目錄META-INF下建spring-bean.xml文件,並填充對應的bean配置,bean需要配置id或者name值,IOC容器唯一即可,class配置定義的實體路徑,對應的property設置初始化屬性。

<code>
<beans> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean>
<property>
<property>
/<bean>
/<beans>/<code>

輸出

創建一個BeanFactory對象,用ClassPathXmlApplicationContext實例化,簡單說一下BeanFactory作為IOC容器的底層基礎,可以說IOC容器就是BeanFactory,ClassPathXmlApplicationContext是IOC容器的功能擴展;ClassPathXmlApplicationContext需要傳入資源文件的路徑,在通過getBean方法獲取具體的實體類,就是結果輸出。

<code> //xml注入
BeanFactory classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-bean.xml");
UserXml userXml = classPathXmlApplicationContext.getBean(UserXml.class);
System.out.println("userXml XML注入對象:" userXml);/<code>

註解注入

註解是在spring2.0.3之後才出現的,大量應用也是在springboot的普及下,大家才慢慢接受。其主要好處就是操作簡單,通過簡單的註解就可以標識成bean組件,而且擴展了各種層次的註解,比如@Service、@Service、@Repository,都是基於@Component註解實現派生。

實體定義

實體通XML實體作用類似,這裡新建一個類,用去區分不同的bean實現方式。

<code>public class UserAnnotation {
private String id;
private String name;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "User{"
"id='" id '\\''
", name='" name '\\''
'}';
}/<code>

註解配置

正常情況下我們是通過標準註解@Configuration進行掃描注入,我們這裡直接配置類即可,在這個類裡面實例化bean組件,並進行初始化操作。

<code>@Configuration
public class UserConfiguration {
@Bean
public UserAnnotation userAnnotation(){

UserAnnotation userAnnotation = new UserAnnotation();
userAnnotation.setId("11");
userAnnotation.setName("java圈");
return userAnnotation;
}
}/<code>

輸出

AnnotationConfigApplicationContext也是BeanFactory的一種實現,和ClassPathXmlApplicationContext功能類似,只是加載渠道不一樣,把定義的配置類註冊到IOC容器,調用register方法,這裡需要注意,下一步需要調refresh方法就行bean的裝載工作,然後通過getBean獲取具體的實體,就行輸出。

<code> //註解注入
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(UserConfiguration.class);
annotationConfigApplicationContext.refresh();
UserAnnotation userAnnotation = annotationConfigApplicationContext.getBean(UserAnnotation.class);
System.out.println("UserAnnotation註解注入" userAnnotation);/<code>

BeanDefinition注入

BeanDefinition是BeanFactory的底層實現,包括上面提到的方式,底層也是基於BeanDefinition實現的,一個bean組件對應一個BeanDefinition,但是實際操作過程中不會這個用,只是僅供參考。

實體定義

實體通XML實體作用類似,這裡新建一個類,用去區分不同的bean實現方式。

<code>public class UserBeanDefinition {
private String id;
private String name;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "User{"
"id='" id '\\''
", name='" name '\\''
'}';
}
}/<code>

輸出

通過BeanDefinitionBuilder的genericBeanDefinition實例化一個構造器,傳入的參數就是實體類,構建之後做初始化操作,之後BeanDefinition聲明調用getBeanDefinition方法,通過getPropertyValues回去bean的具體參數進行結束輸出。

<code>//BeanDefinition注入
BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserBeanDefinition.class);
definitionBuilder.addPropertyValue("id", "11");
definitionBuilder.addPropertyValue("name", "java圈");
BeanDefinition beanDefinition = definitionBuilder.getBeanDefinition();
String beanClassName = beanDefinition.getBeanClassName();
MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
String id = mutablePropertyValues.getPropertyValue("id").getValue().toString();
String name = mutablePropertyValues.getPropertyValue("name").getValue().toString();
System.out.println("BeanDefinition注入對象UserBeanDefition{id=" id ",name=" name "}");/<code>

結果輸出

輸出結果分別是xml注入、annotation注入,BeanDefinition注入。

<code>userXml XML注入對象:User{id='11', name='java圈'}

UserAnnotation註解注入User{id='11', name='java圈'}

BeanDefinition注入對象UserBeanDefition{id=11,name=java圈}/<code>

源代碼:https://github.com/itrickzhang/spring-demo

轉載自:https://blog.csdn.net/zhangchangbin123/article/details/103983276


分享到:


相關文章: