您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“如何理解Spring Ioc容器Bean”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何理解Spring Ioc容器Bean”吧!
Bean在Ioc容器中可以有一個或多個名稱,但這些名稱在容器內(nèi)必須唯一,在Xml中配置id和name屬性就可以為Bean起別名。
<bean id="user" name="zhangsan,lisi" class="com.example.demo.spring.UserBean"/>
這樣我們就可以通過名稱user、zhangsan、lisi獲取UserBean的實例。
當(dāng)然如果你沒有給UserBean配置id/name屬性,Spring Ioc容器會未Bean自動生成一個類名首字符小寫的別名。
除此之外還可以使用<alias name="user" alias="wangwu"></alias
配置別名。
<bean class=""/>
class屬性代表著Ioc要實例化的Bean的類型,通常Ioc容器會通過反射機制調(diào)用其無參構(gòu)造函數(shù)直接創(chuàng)建Bean。
除此之外還可以配置使用靜態(tài)工廠方法或者實例工廠方法來實例化對象。
/** * 使用靜態(tài)工廠實例化Bean * 配置factory-method屬性 */ public class StaticFactory { private static UserBean userBean = new UserBean(); public static UserBean createInstance() { return userBean; } }
<bean id="user1" class="com.example.demo.spring.StaticFactory" factory-method="createInstance"></bean>
使用class來指定包含static工廠方法的類型,使用factory-method指定創(chuàng)建bean實例的工廠方法。
/** * 實例工廠方法 * 配置factory-bean和factory-method屬性 */ public class InstanceFactory { public UserBean createUserBeanInstance() { return new UserBean(); } }
<bean id="instanceFactory" class="com.example.demo.spring.InstanceFactory"></bean> <bean id="user2" factory-bean="instanceFactory" factory-method="createUserBeanInstance"></bean>
使用factory-bean指定要創(chuàng)建Bean實例的方法的Bean的名稱,使用factory-method指定工廠方法名稱。
依賴注入指Ioc要創(chuàng)建A的實例,但A內(nèi)部又依賴于B的實例,依賴注入主要有兩種類型:基于構(gòu)造函數(shù)的依賴注入和基于Setter的依賴注入。
構(gòu)造函數(shù)注入
基于構(gòu)造函數(shù)的依賴注入主要依賴于<constructor-arg></constructor-ar
標(biāo)簽。
使用
type
屬性顯式指定了構(gòu)造函數(shù)參數(shù)的類型<bean id="user" class="com.example.demo.spring.UserBean"> <constructor-arg type="java.lang.Integer" value="15"></constructor-arg></bean>指定type的配置為Integer并且只有一個參數(shù),所以Ioc在創(chuàng)建UserBean實例是會使用如下的構(gòu)造函數(shù)
public UserBean(Integer age) { this.age = age; System.out.println("1");}
使用
index
屬性來顯式指定構(gòu)造函數(shù)參數(shù)的索引<bean id="user" class="com.example.demo.spring.UserBean"><!-- <constructor-arg type="java.lang.Integer" value="15"></constructor-arg>--> <constructor-arg index="0" value="16"></constructor-arg> <constructor-arg index="1" value="張三"></constructor-arg> </bean>指定了有兩個參數(shù),所以會使用如下構(gòu)造函數(shù)
public UserBean(Integer age, String name) { this.age = age; this.name = name; System.out.println("2");}
使用構(gòu)造函數(shù)參數(shù)名稱
<bean id="user" class="com.example.demo.spring.UserBean"> <constructor-arg name="age" value="85"></constructor-arg></bean>
Setter注入
使用Setter注入,必須保證要注入的屬性具有setter方法,setter方法可以利用idea自動生成。主要依賴于<property></property>
<bean id="user" class="com.example.demo.spring.UserBean"> <property name="name" value="張三"></property> <property name="age" value="18"></property></bean>
list屬性的配置
<bean id="user" class="com.example.demo.spring.UserBean"> <property name="phone"> <list> <value>123456789</value> <value>99999</value> <ref bean="user1"></ref> </list> </property></bean>
Map屬性的配置
<property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property>
bean的作用域通過scope屬性配置
scope | 描述 |
singleton | Spring Ioc容器中只有一個實例 |
prototype | 每次獲取bena實例都重新創(chuàng)建一個新的 |
request | HTTP 請求的生命周期 |
session | HTTP Session 的生命周期 |
application | ServletContext 的生命周期 |
websocket | WebSocket 的生命周期 |
InitializingBean: Bean在初始化時調(diào)用,等價于init-method屬性和@PostConstruct注解,如果不指定初始化方法,Spring 默認(rèn)會調(diào)用init()方法
DisposableBean:Bean在銷毀時調(diào)用,等價于destroy-method屬性和@PreDestroy注解,Spring 默認(rèn)調(diào)用destroy()方法
Lifecycle:容器啟動或關(guān)閉時回調(diào),該回調(diào)是通過 LifecycleProcessor 完成回調(diào)
ApplicationContextAware:自動獲取ApplicationContext的引用
BeanNameAware:獲取該對象在Ioc容器中的名稱,該方法在調(diào)用 afterPropertiesSet 或自定義的 init-method 之前調(diào)用
除此之外還有其他的Aware,功能是為了獲得接口申明的依賴
name | dependency |
ApplicationEventPublisherAware | ApplicationContext的事件發(fā)布者 |
BeanFactoryAware | Bean工廠 |
ServletConfigAware | 容器中的ServletConfig(Web容器) |
ServletContextAware | 容器中運行的ServletContext(Web容器) |
BeanClassLoaderAware | Bean的類加載器 |
parent屬性用來指定要繼承的配置數(shù)據(jù),parent所指向的bean的定義必須要指定abstract屬性為true,聲明為抽象定義的Bean不能通過id獲取實例,parent中定義的屬性如果子bean重新配置,則會覆蓋父bean的配置。
<bean id="inheritedTestBean" abstract="true" class="com.example.demo.spring.TestBean"> <property name="name" value="parent"></property> <property name="age" value="1"></property></bean><bean id="inheritedTestBean" abstract="true"> <property name="name" value="parent"></property> <property name="age" value="1"></property></bean><bean id="inheritsWithDifferentClass" class="com.example.demo.spring.DrivedTestBean" parent="inheritedTestBean"> <property name="name" value="override"></property> <property name="addr" value="西安"></property></bean>
BeanPostProcessor
BeanPostProcessor接口提供了兩個方法postProcessBeforeInitialization(init之前調(diào)用)和 postProcessAfterInitialization (init之后調(diào)用),主要為了在Spring容器完成實例化、配置和初始化之后實現(xiàn)一些自定義的實例化或依賴解析邏輯等。一個容器中可以注冊多個BeanPostProcessor,要控制他們的執(zhí)行順序,只需要繼承Ordered接口。
public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("************postProcessBeforeInitialization*********** + " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("************postProcessAfterInitialization*********** + " + beanName); return bean; }}
BeanFactoryPostProcessor
BeanFactoryPostProcessor是用來在beans進行初始化前修改bean的配置元數(shù)據(jù)。與BeanPostProcessor的主要區(qū)別是:BeanPostProcessor對Bean實例進行操作,BeanFactoryPostProcessor是對Bean的配置元數(shù)據(jù)進行操作。
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("postProcessBeanFactory >>>"); BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition("message1"); System.out.println(beanDefinition.getBeanClassName()); } @Override public int getOrder() { return 1; } public void init() { System.out.println("MyBeanFactoryPostProcessor init"); }}
PropertyPlaceholderConfigurer
PropertyPlaceholderConfigurer
可以從單獨獨文件中的 bean 定義外部化屬性值,不同的環(huán)境中加載不同的配置文件。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="jdbc.properties"></property></bean><bean id="datasource" class="com.example.demo.spring.DataSource"> <property name="userName" value="${datasource.userName}"></property> <property name="password" value="${datasource.password}"></property></bean>
也可以使用
<context:property-placeholder location="classpath:com/something/jdbc.properties"/>
PropertyOverrideConfigure
用來覆蓋Bean的屬性。
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="locations" value="jdbc.properties"></property></bean><bean id="datasource" class="com.example.demo.spring.DataSource"> <property name="password" value="12311"></property></bean>
jdbc.properties
datasource.userName=rootdatasource.password=root
最終Bean password值會是root被PropertyOverrideConfigurer覆蓋。
FactoryBean是一個特殊的接口,它不同于BeanFactory,BeanFacoty是Spring的工廠,而FactoryBean是容器中的一個特殊bean,可以創(chuàng)建指定的類型Bean的實例。
public class DataSourceFanctoryBean implements FactoryBean<DataSource> { @Override public DataSource getObject() throws Exception { System.out.println(1); DataSource dataSource = new DataSource(); dataSource.setUserName("張三"); dataSource.setPassword("123456"); return dataSource; } @Override public Class<?> getObjectType() { return DataSource.class; } @Override public boolean isSingleton() { return false; }}
<bean id="datasource" class="com.example.demo.spring.DataSourceFanctoryBean"></bean>直接通過beanfactory.getBean("datasource")獲取則是 DataSource 的實例,在id前加 & 則獲取的是 DataSourceFanctoryBean 的實例
到此,相信大家對“如何理解Spring Ioc容器Bean”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。