Spring4深入理解IOC&DI04----Bean配置方式(全類名,工廠方法,FactoryBean),配置形式(基於XML和註解),泛型依賴注入
一、Bean的配置方式
Bean 的配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法 & 例項工廠方法)、FactoryBean
1-1.通過靜態工廠方式配置Bean
--•呼叫靜態工廠方法建立Bean是將物件建立的過程封裝到靜態方法中.當客戶端需要物件時,只需要簡單地呼叫靜態方法,而不同關心建立物件的細節. --•要宣告通過靜態方法建立的 Bean,需要在Bean的class屬性裡指定擁有該工廠的方法的類,同時在factory-method屬性裡指定工廠方法的名稱.最後,使用<constrctor-arg>元素為該方法傳遞方法引數. 1-2.通過例項工廠方式配置Bean•例項工廠方法: 將物件的建立過程封裝到另外一個物件例項的方法裡.當客戶端需要請求物件時,只需要簡單的呼叫該例項方法而不需要關心物件的建立細節. •要宣告通過例項工廠方法建立的 Bean –在 bean 的factory-bean屬性裡指定擁有該工廠方法的Bean –在 factory-method屬性裡指定該工廠方法的名稱 –使用 construtor-arg元素為工廠方法傳遞方法引數
/** * InstanceCarFactory:例項工廠方法 * 例項工廠的方法,即需要先建立工廠本身,再呼叫工廠的例項方法來返回bean的例項 * * @author Lcw 2015/11/12 */ public class InstanceCarFactory { private Map<String, Car> cars = null; public InstanceCarFactory() { cars = new HashMap<String, Car>(); cars.put("audi", new Car("audi", 500000)); cars.put("ford", new Car("ford", 600000)); } public Car getCar(String brand) { return cars.get(brand); } }
/** * StaticCarFactory:靜態工廠方法:直接呼叫某一個類的靜態方法就可以返回Bean例項 */ public class StaticCarFactory { private static Map<String , Car> cars = new HashMap<String, Car>(); static { cars.put("audi",new Car("audi", 30000)); cars.put("ford",new Car("ford", 40000)); } //靜態工廠方法: 注意:要在配置檔案XML裡配置Car而不是StaticCarFactory public static Car getCar(String name) { return cars.get(name); } }
<?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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--通過靜態工廠方法來配置bean, 注意不是配置靜態工廠方法例項,而是配置bean例項-->
<!--factory-method: 指向靜態工廠方法的名字
constructor-arg:如果工廠方法需要傳入引數,則使用constructor-arg來配置引數-->
<bean id="car1" class="Spring4_IOC.bean.factory.StaticCarFactory"
factory-method="getCar">
<constructor-arg value="audi"/>
</bean>
<!--配置例項工廠的例項-->
<bean id="carFactory" class="Spring4_IOC.bean.factory.InstanceCarFactory"/>
<!-- 通過例項工廠方法來配置bean-->
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="ford"/>
</bean>
</beans>
/**
* Bean 的配置方式:-、通過全類名(反射);二、通過工廠方法(靜態工廠方法 & 例項工廠方法);三、FactoryBean
*
* 靜態工廠方法:直接呼叫某一個類的靜態方法就可以返回Bean例項
* 例項工廠方法:例項工廠的方法,即需要先建立工廠本身,再呼叫工廠的例項方法來返回bean的例項
*/
@Test
public void testStaticFactory() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-factory.xml");
//測試靜態工廠方法
Car car1 = (Car) ctx.getBean("car1");
System.out.println(car1);
//例項工廠方法
Car car2 = (Car) ctx.getBean("car2");
System.out.println(car2);
}
1-3.實現 FactoryBean 介面在 Spring IOC 容器中配置 Bean•Spring 中有兩種型別的Bean,一種是普通Bean,另一種是工廠Bean,即FactoryBean. •工廠 Bean 跟普通Bean不同,其返回的物件不是指定類的一個例項,其返回的是該工廠Bean的getObject方法所返回的物件
/**
* CarFactoryBean:自定義的factoryBean需要實現FactoryBean
*/
public class CarFactoryBean implements FactoryBean<Car> {
private String brand;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public CarFactoryBean() {
}
//下面是三個實現方法
//返回bean的物件
public Car getObject() throws Exception {
return new Car("BMW" , 500000);
}
//返回bean的型別Class<?> 中?表示一個未知的類
public Class<?> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return true;
}
}
<?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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--
通過factoryBean來配置Bean的例項
class:指向FactoryBean的全類名
property:配置FactoryBean的屬性
但實際返回的例項確是FactoryBean的getObject()返回的例項-->
<bean id="car" class="Spring4_IOC.bean.CarFactoryBean">
<property name="brand" value="BMW"/>
</bean>
</beans>
/**
* Bean 的配置方式:-、通過全類名(反射);二、通過工廠方法(靜態工廠方法 & 例項工廠方法);三、FactoryBean
*
* 測試FactoryBean
* Spring 中有兩種型別的 Bean, 一種是普通Bean, 另一種是工廠Bean, 即FactoryBean
*/
@Test
public void testFactoryBean() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-beanFactory.xml");
Car car = (Car) ctx.getBean("car"); //注意這個在類是Car!
System.out.println(car);
}
二、Bean的配置形式
配置形式:基於 XML 檔案的方式;基於註解的方式(基於註解配置 Bean;基於註解來裝配 Bean 的屬性)在 classpath 中掃描元件
•元件掃描(componentscanning): Spring能夠從classpath下自動掃描,偵測和例項化具有特定註解的元件. •特定元件包括: –@Component: 基本註解,標識了一個受Spring管理的元件 –@Respository:標識持久層元件 –@Service: 標識服務層(業務層)元件 –@Controller: 標識表現層元件 •對於掃描到的元件,Spring有預設的命名策略:使用非限定類名,第一個字母小寫.也可以在註解中通過value屬性值標識元件的名稱 •當在元件類上使用了特定的註解之後,還需要在Spring的配置檔案中宣告<context:component-scan>: –base-package 屬性指定一個需要掃描的基類包,Spring容器將會掃描這個基類包裡及其子包中的所有類. –當需要掃描多個包時, 可以使用逗號分隔. –如果僅希望掃描特定的類而非基包下的所有類,可使用 resource-pattern屬性過濾特定的類,示例: –<context:include-filter>子節點表示要包含的目標類 –<context:exclude-filter>子節點表示要排除在外的目標類 –<context:component-scan>下可以擁有若干個<context:include-filter>和<context:exclude-filter>子節點
以下 類那放在這個檔案下Spring4_IOC.annotation
@Component
public class TestObject {
}
respository介面跟實現類public interface UserRepository {
void save();
}
//介面實現一般用介面名
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
public void save() {
System.out.println("UserRepository Save...");
}
}
Service層跟controller@Service
public class UserService {
//@Autowired(required=false) //如果沒有這個類,輸出為null
@Autowired
private UserRepository userRepository;
public void add() {
System.out.println("UserService add...");
userRepository.save();
}
}
@Controller
public class UserController {
@Autowired
private UserService userService;
public void execute() {
System.out.println("UserController execute...");
userService.add();
}
}
<?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 http://www.springframework.org/schema/context/spring-context.xsd">
<!--指定Spring IOC容器掃描的包-->
<!--可以通過resource-pattern指定掃描的資源-->
<!--<context:component-scan base-package="Spring4_IOC.annotation"
resource-pattern="repository/*.class"></context:component-scan>-->
<!--exclude-filter: 子節點指定排除哪些指定表示式的元件-->
<!--include-filter:子節點指定包含哪些表示式的元件,該子節點需要use-default-filters="false"配合使用-->
<context:component-scan base-package="Spring4_IOC.annotation" >
<!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>-->
<!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>-->
<!--<context:exclude-filter type="assignable" expression="com.changwen.spring4.annotation.repository.UserRepository"/>-->
<!--<context:include-filter type="assignable" expression="com.changwen.spring4.annotation.repository.UserRepository"/>-->
</context:component-scan>
</beans>
@Test
public void testAnnotation() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-annotation.xml");
TestObject to = (TestObject) ctx.getBean("testObject");
System.out.println(to);
//類UserController第一個字母小寫 userController
UserController userController = (UserController) ctx.getBean("userController");
System.out.println(userController);
userController.execute();
UserService userService = (UserService) ctx.getBean("userService");
System.out.println(userService);
UserRepository userRepository = (UserRepository) ctx.getBean("userRepository");
System.out.println(userRepository);
}
<context:include-filter>和<context:exclude-filter>子節點支援多種型別的過濾表示式2-1.元件裝配
•<context:component-scan>元素還會自動註冊AutowiredAnnotationBeanPostProcessor例項,該例項可以自動裝配具有@Autowired和@Resource、@Inject註解的屬性. 1).使用 @Autowired自動裝配Bean•@Autowired註解自動裝配具有相容型別的單個Bean屬性 –構造器,普通欄位(即使是非public),一切具有引數的方法都可以應用@Authwired註解 –預設情況下,所有使用@Authwired註解的屬性都需要被設定.當Spring找不到匹配的Bean裝配屬性時,會丟擲異常,若某一屬性允許不被設定,可以設定@Authwired註解的required屬性為false –預設情況下,當IOC容器裡存在多個型別相容的Bean時,通過型別的自動裝配將無法工作.此時可以在@Qualifier註解裡提供Bean的名稱.Spring允許對方法的入參標註@Qualifiter已指定注入Bean的名稱 –@Authwired註解也可以應用在陣列型別的屬性上,此時Spring將會把所有匹配的Bean進行自動裝配. –@Authwired註解也可以應用在集合屬性上,此時Spring讀取該集合的型別資訊,然後自動裝配所有與之相容的Bean. –@Authwired註解用在java.util.Map上時,若該Map的鍵值為String,那麼Spring將自動裝配與之Map值型別相容的Bean,此時Bean的名稱作為鍵值
2).使用 @Resource或@Inject自動裝配Bean
•Spring 還支援 @Resource和@Inject註解,這兩個註解和@Autowired註解的功用類似 •@Resource 註解要求提供一個Bean名稱的屬性,若該屬性為空,則自動採用標註處的變數或方法名作為Bean的名稱 •@Inject 和 @Autowired註解一樣也是按型別匹配注入的Bean,但沒有reqired屬性 •建議使用 @Autowired註解
三、泛型依賴注入
•Spring 4.x 中可以為子類注入子類對應的泛型型別的成員變數的引用public class BaseRepository<T> {
}
public class BaseService<T> {
@Autowired
protected BaseRepository<T> repository;
public void add() {
System.out.println("add...");
System.out.println(repository);
}
}
@Service
public class UserService extends BaseService<User> {
}
public class User {
private String userName;
private List<Car> cars;
private String wifeName;
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
System.out.println("setWifhName: " + wifeName);
this.wifeName = wifeName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public User() {
System.out.println("User's Construtor...");
}
@Override
public String toString() {
return "User [userName=" + userName + ", cars=" + cars + "]";
}
public void init(){
System.out.println("init method...");
}
public void destroy(){
System.out.println("destroy method...");
}
}
@Repository
public class UserRepository extends BaseRepository<User>{
}
配置檔案<?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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="Spring4_IOC.di">
</context:component-scan>
</beans>
/**
* Spring 4.x 新特性:泛型依賴注入
*/
@Test
public void testDI() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring4_IOC/beans-generic.xml");
Spring4_IOC.di.UserService userService = (Spring4_IOC.di.UserService) ctx.getBean("userService");
System.out.println(userService);
userService.add();
}
[email protected] add... [email protected] |
•Spring 允許通過 <import>將多個配置檔案引入到一個檔案中,進行配置檔案的整合。這樣在啟動Spring容器時,僅需要指定這個合併好的配置檔案就可以。 •import元素的resource屬性支援Spring的標準的路徑資源
相關推薦
Spring4深入理解IOC&DI04----Bean配置方式(全類名,工廠方法,FactoryBean),配置形式(基於XML和註解),泛型依賴注入
一、Bean的配置方式 Bean 的配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法 & 例項工廠方法)、FactoryBean 1-1.通過靜態工廠方式配置Bean --•呼叫靜態工廠方法建立Bean是將物件建立的過程封裝到靜態方法中.當客
Spring4新特性泛型依賴注入
什麼叫做泛型依賴注入呢? 就是帶泛型的兩個父類他們之間有引用關係, 子類各自繼承他們,子類之間彼此之間也會有父類間的引用關係。 舉例: 兩個父類:之間有引用關係。 package one;
Spring-13:泛型依賴注入(Spring4.X新特性)
Spring 4.x 中可以為子類注入子類對應的泛型型別的成員變數的引用。 首先建立兩個泛型基類: BaseRepository<T> 和 BaseService<T> public class BaseRepository<T> {
淺談spring4泛型依賴注入
Spring 4.0版本中更新了很多新功能,其中比較重要的一個就是對帶泛型的Bean進行依賴注入的支援。Spring4的這個改動使得程式碼可以利用泛型進行進一步的精簡優化。 1. 泛型依賴注入的優點 泛型依賴注入就是允許我們在使用spring進行依賴注入的同時,利用泛型的
Spring:依賴注入(註解方式)、泛型依賴注入
註解方式實現依賴注入支援手工裝配和自動裝配(慎用) 一般是宣告bean和bean直接的依賴關係的時候用比較好 使用註解方式時,也支援給Field注入值(在XML中不可以給Field注入)。另外就是setter方式注入。 @Resource註解在spring安裝目錄的lib\
Spring4深入理解----事務(宣告式事務和xml配置事務,事務傳播屬性,事務其他屬性(隔離級別&回滾&只讀&過期))
•事務管理是企業級應用程式開發中必不可少的技術, 用來確保資料的完整性和一致性. •事務就是一系列的動作,它們被當做一個單獨的工作單元.這些動作要麼全部完成,要麼全部不起作用 •事務的四個關鍵屬性(ACID) –原子性(atomicity):事務是一
深入理解IOC模式及Unity框架
理解 rain 框架 播放器 url 播放 builder 說明 title 深入理解IOC模式及Unity框架 研究了下,有幾篇博客確實已經說得很清楚了 1、IoC模式:http://www.cnblogs.com/qqlin/archive/
3. Spring: 深入理解IoC
3. Spring: 深入理解IoC IoC 是 Spring容器的核心,AOP、宣告式事務等功能都依賴於此功能 解耦過程例項 問題場景 解耦過程 IoC解耦 介面具體實現類的控制權從呼叫類
深入理解IOC
1. IoC理論的背景 我們都知道,在採用面向物件方法設計的軟體系統中,它的底層實現都是由N個物件組成的,所有的物件通過彼此的合作,最終實現系統的業務邏輯。 圖1:軟體系統中耦合的物件 如果我們開啟機械式手錶的後蓋,就會看到與上面類似的情形,各個齒輪分別帶動時針、分針和秒針順時針
深入理解字串的底層儲存方式
引言 以下討論的,包括圖示,都是基於JDK1.8以上。因為JDK1.7的常量池在方法區,而不是在Java堆中 先了解字串常量在記憶體的表示方式,接著瞭解字串物件在記憶體的表示方式。在瞭解兩種字串表現方式後,String.intern()就將會很容易理解。 關
深入理解Spring的兩大特徵(IOC和AOP)
眾所周知,Spring的核心特性就是IOC和AOP,IOC(Inversion of Control),即“控制反轉”;AOP(Aspect-OrientedProgramming),即“面向切面程式設計”。參考書《Spring In Action》,下面分享一
springboot的5種讀取配置方式(1):直接讀取bean
1.直接讀取bean:/** * 學生實體類 * Created by ASUS on 2018/5/4 */ public class Student { private String
《深入理解Nginx》閱讀與實踐(一):Nginx安裝配置與HelloWorld
#include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> static char* ngx_http_mytest(ngx_conf_t *cf,ngx_command_t *cmd,
JAVAWEB開發之Spring詳解之——Spring的入門以及IOC容器裝配Bean(xml和註解的方式)、Spring整合web開發、整合Junit4測試
public class BeanFactory{ public UserService getUserService(){ // 反射+配置檔案 return Class.forName(類名).newInStance(); } } xml、pro
深入理解IOC控制反轉及應用例項
一、IOC雛形 1、程式V1.0 話說,多年以前UT公司提出一個需求,要提供一個系統,其中有個功能可以在新春佳節之際給公司員工傳送一封郵件。郵件中給大家以新春祝福,並告知發放一定數額的過節費。 經分析,決定由張三、李四和王五來負責此係統的開發。 其中:由張三
laravel 服務容器例項——深入理解IoC模式
剛剛接觸laravel,對於laravel的服務容器不是很理解。看了《Laravel框架關鍵技術解析》和網上的一些資料後對於服務容器有了一些自己的理解,在這裡分享給大家 1、依賴 IoC模式主要是用來解決系統元件之間相互依賴關係的一種模式。那麼什麼是依賴呢?下面給出依賴的例
深入理解Activity啟動流程(二)–Activity啟動相關類的類圖
b- ive ava ani affinity server 組織 詳細 pac 本文原創作者:Cloud Chou. 歡迎轉載,請註明出處和本文鏈接 本系列博客將詳細闡述Activity的啟動流程,這些博客基於Cm 10.1源碼研究。 在介紹Activity的詳細啟動流程
深入理解Java虛擬機- 學習筆記 - 虛擬機類加載機制
支持 pub eth 獲取 事件 必須 string 沒有 字節碼 虛擬機把描述類的數據從Class文件加載道內存,並對數據進行校驗,轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。在Java裏,類型的加載、連接和初始化過程都是在程序
SpringMVC基於代碼的配置方式(零配置,無web.xml)
-c size ons imp .net rri import 右鍵 無需 基於配置文件的web項目維護起來可能會更方便,可是有時候我們會有一些特殊的需求,比方防止客戶胡亂更改配置,這時候我們須要給配置隱藏到代碼中。 1.創建一個動態web項目(無需w
深入理解JAVA虛擬機閱讀筆記——虛擬機類加載機制
info 程序 動態 alt 訪問 什麽 hand jdk 靜態方法 虛擬機把描述類的Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。 在Java語言中,類型的加載、連接