前言
對於傳統的應用程序,一般通過new object()來創建對象,主動權和創建時機由自己把控,而IOC意味着將創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象。對象的獲取由主動變爲被動,這就是IOC控制反轉的設計思想。
快速入門
pom依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Spring</groupId>
<artifactId>SpringLearn</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>4.1.4.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring Core -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Context -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
代碼示例
創建HelloWorld接口
package com.demo;
public interface HelloWorld {
void sayHello();
}
創建接口實現類
package com.demo;
public class SpringHelloWorld implements HelloWorld {
public void sayHello() {
System.out.println("Spring say Hello!");
}
}
創建service層
package com.demo;
public class HelloWorldService {
//@Autowired
//@Qualifier("strutsHelloWorld")
private HelloWorld hello;
private String name;
public void setHelloWorld(HelloWorld hello) {
this.hello = hello;
}
public void setName(String name){
this.name = name;
}
public HelloWorld getHelloWorld() {
System.out.println(this.name);
return hello;
}
}
配置bean文件,property的name屬性的值需要與HelloWorldService類的set方法名後半部分名稱一致,比如setHelloWorld方法,則name值爲helloWorld。ref指向創建的對象springHelloWorld,作用是把對象傳遞給HelloWorldService的HelloWorld屬性,該屬性必須擁有set方法(上述代碼的setHelloWorld方法)才能注入成功。
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--context:annotation-config /-->
<!-- 聲明springHelloWorld對象,由spring創建 -->
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<!-- 聲明helloWorldService對象,由spring創建 -->
<bean id="helloWorldService"
class="com.demo.HelloWorldService">
<!--注入springHelloWorld對象,需要setHelloWorld方法-->
<property name="helloWorld" ref="springHelloWorld"/>
<!--注入name變量值,需要setName方法-->
<property name="name" value="Tomandy"/>
</bean>
</beans>
創建測試類
package com.demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestHelloWorld {
public static void main(String[] args) {
//加載配置文件,默認查找classpath路徑下的文件
ApplicationContext context =
new ClassPathXmlApplicationContext("helloWorldBeans.xml");
//spring默認創建是單實例的作用域
HelloWorldService helloWorldService =
(HelloWorldService) context.getBean("helloWorldService");
HelloWorld helloWorld = helloWorldService.getHelloWorld();
helloWorld.sayHello();
}
}
運行測試類,輸出結果爲
"C:\Program Files (x86)\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\lib\idea_rt.jar=36108:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\github\SpringLearn\target\test-classes;D:\github\SpringLearn\target\classes;C:\Users\lenovo\.m2\repository\org\springframework\spring-core\4.1.4.RELEASE\spring-core-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-context\4.1.4.RELEASE\spring-context-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-aop\4.1.4.RELEASE\spring-aop-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-beans\4.1.4.RELEASE\spring-beans-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-expression\4.1.4.RELEASE\spring-expression-4.1.4.RELEASE.jar" com.demo.TestHelloWorld
三月 01, 2019 2:13:54 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@197848c: startup date [Fri Mar 01 14:13:54 CST 2019]; root of context hierarchy
三月 01, 2019 2:13:54 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [helloWorldBeans.xml]
Tomandy
Spring say Hello!
Process finished with exit code 0
通過以上示例,可輕鬆瞭解IOC的使用了,即通過xml配置文件,spring可以幫助我們創建對象springHelloWorld,並注入helloWorldService中,上述代碼使用的setter注入方式,還可以通過構造函數、註解、靜態工廠、實例工廠來注入,下面文章再說明。
除了通過ClassPathXmlApplicationContext去加載spring的配置文件,還可以通過FileSystemXmlApplicationContext去加載,區別在於前者默認查找classpath路徑下的文件,後者默認查找項目工作路徑,即項目的根目錄,文章《關於Spring IOC (DI-依賴注入)你需要知道的一切》舉例如下。
//默認查找classpath路徑下的文件
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml");
//多文件,也可傳遞數組
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml","spring/spring-ioc2.xml",.....);
//默認爲項目工作路徑 即項目的根目錄
FileSystemXmlApplicationContext applicationContext= new FileSystemXmlApplicationContext("/src/main/resources/spring/spring-ioc.xml");
//也可以讀取classpath下的文件
FileSystemXmlApplicationContext applicationContext=new FileSystemXmlApplicationContext("classpath:spring/spring-ioc.xml");
//使用前綴file 表示的是文件的絕對路徑
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:D:/app.spring.xml");
//多文件與ClassPathXmlApplicationContext相同
基於xml的自動裝配
上述例子bean文件配置了property屬性,實際屬於手工裝配,spring也提供了自動裝配的方式,分別有byName,byType,constructor三種方式,下面通過舉例來說明他們之間的區別。
- byName,顧名思義就是按照名稱匹配。根據bean名稱去和set方法的後半部分名稱匹配,如果一致,則注入成功,否則失敗。
配置bean文件
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean id="helloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
autowire="byName"
class="com.demo.HelloWorldService">
</bean>
</beans>
創建HelloWorldService
package com.demo;
public class HelloWorldService {
private HelloWorld helloWorld;
public void setHelloWorld(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
byName模式會根據beanid helloWorld去和setHelloWorld方法的後半部分名稱(HelloWorld)比對,如果(首字母轉換爲大寫)一致則注入成功。
- byType,即按照類型匹配。Spring容器會基於反射查看bean定義的類,然後找到與set方法參數類型相同的bean來注入,需要通過set方法來實現。
配置bean文件,注意用到了autowire屬性。
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
autowire="byType"
class="com.demo.HelloWorldService">
</bean>
</beans>
創建HelloWorldService
package com.demo;
public class HelloWorldService {
private HelloWorld helloWorld;
public void setHelloWorld(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
運行測試類,輸出結果爲
Spring say Hello!
當存在多個相同類型的bean時,使用byType方式會報錯,此時可以通過autowire-candidate="false"來跳過相同類型的bean。
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="springHelloWorld1"
autowire-candidate="false"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
autowire="byType"
class="com.demo.HelloWorldService">
</bean>
</beans>
- constructor,在該模式下Spring容器同樣會嘗試找到那些類型與構造函數相同匹配的bean注入。當存在多個類型相同bean時,按名稱優先匹配,如果沒有找到對應名稱,則注入失敗,此時可以使用autowire-candidate=”false” 過濾來解決。
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<!--如果存在多個相同類型的,則按byName來匹配-->
<bean id="helloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorld2"
autowire-candidate="false"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
autowire="constructor"
class="com.demo.HelloWorldService">
</bean>
</beans>
package com.demo;
public class HelloWorldService {
private HelloWorld helloWorld;
public HelloWorldService(HelloWorld helloWorld){
this.helloWorld = helloWorld;
}
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
依賴注入
除了上文提到的setter注入,還可以通過構造函數、註解、靜態工廠、實例工廠注入。
構造函數注入
spring容器會根據bean中指定的構造函數參數來決定調用那個構造函數。
創建HelloWorldService
package com.demo;
import java.util.List;
import java.util.Map;
public class HelloWorldService {
//@Autowired
//@Qualifier("strutsHelloWorld")
private HelloWorld hello;
private String name;
private List<String> list;
private Map<String, String> map;
public HelloWorldService(HelloWorld hello, String name, List<String> list, Map<String, String> map) {
this.hello = hello;
this.name = name;
this.list = list;
this.map = map;
}
public HelloWorld getHelloWorld() {
System.out.println(this.name);
for (int i = 0; i < list.size(); i++) {
System.out.println("第" + i + "個列表值:" + list.get(i));
}
for (String key : map.keySet()) {
System.out.println("key爲:" + key + " value爲:" + map.get(key));
}
return hello;
}
}
配置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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--context:annotation-config /-->
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
class="com.demo.HelloWorldService">
<!--注入,需要set方法-->
<!--
<property name="helloWorld" ref="springHelloWorld"/>
<property name="name" value="Tomandy"/>
-->
<constructor-arg ref="springHelloWorld"/>
<constructor-arg type="java.lang.String" value="Tomandy"/>
<constructor-arg>
<list>
<value>tom1</value>
<value>tom2</value>
</list>
</constructor-arg>
<constructor-arg>
<map>
<entry key="key1" value="value1">
</entry>
<entry key="key2" value="value2">
</entry>
</map>
</constructor-arg>
</bean>
</beans>
運行測試後,輸出結果如下。
"C:\Program Files (x86)\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\lib\idea_rt.jar=42191:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\github\SpringLearn\target\test-classes;D:\github\SpringLearn\target\classes;C:\Users\lenovo\.m2\repository\org\springframework\spring-core\4.1.4.RELEASE\spring-core-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-context\4.1.4.RELEASE\spring-context-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-aop\4.1.4.RELEASE\spring-aop-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-beans\4.1.4.RELEASE\spring-beans-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-expression\4.1.4.RELEASE\spring-expression-4.1.4.RELEASE.jar" com.demo.TestHelloWorld
三月 01, 2019 4:17:54 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@197848c: startup date [Fri Mar 01 16:17:54 CST 2019]; root of context hierarchy
三月 01, 2019 4:17:54 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [helloWorldBeans.xml]
Tomandy
第0個列表值:tom1
第1個列表值:tom2
key爲:key1 value爲:value1
key爲:key2 value爲:value2
Spring say Hello!
Process finished with exit code 0
註解注入
需在bean文件加上以下內容,註解注入才生效。
<context:annotation-config />
- 可以通過@Autowired對成員變量、set方法、構造函數進行標註來實現依賴注入,該註解默認按byType匹配,如果需要按byName匹配,可以通過@Qualifier來指定對象的名稱,指定的名稱需與bean文件的對象名稱一致,否則會報錯。
創建HelloWorldService
package com.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class HelloWorldService {
@Autowired
@Qualifier("springHelloWorld")
private HelloWorld helloWorld;
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
配置bean文件
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
class="com.demo.HelloWorldService">
</bean>
</beans>
運行測試類,輸出結果如下。
"C:\Program Files (x86)\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\lib\idea_rt.jar=47086:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\github\SpringLearn\target\test-classes;D:\github\SpringLearn\target\classes;C:\Users\lenovo\.m2\repository\org\springframework\spring-core\4.1.4.RELEASE\spring-core-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-context\4.1.4.RELEASE\spring-context-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-aop\4.1.4.RELEASE\spring-aop-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-beans\4.1.4.RELEASE\spring-beans-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-expression\4.1.4.RELEASE\spring-expression-4.1.4.RELEASE.jar" com.demo.TestHelloWorld
三月 01, 2019 5:48:05 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@197848c: startup date [Fri Mar 01 17:48:05 CST 2019]; root of context hierarchy
三月 01, 2019 5:48:06 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [helloWorldBeans.xml]
Spring say Hello!
Process finished with exit code 0
通過以上例子可發現,通過標註成員變量,可以省略set方法和構造函數,大大簡化了代碼。
- @Resource的功能與@Autowired類似,但不能標註構造函數。默認按照byName進行裝配,名稱可以通過name屬性進行指定,如果沒有指定name屬性,當註解寫在成員變量上時,默認取成員變量名進行byName查找,如果註解寫在setter方法上默認取屬性名進行裝配。 當找不到與名稱匹配的bean時才按照byType進行裝配。
package com.demo;
import javax.annotation.Resource;
public class HelloWorldService {
// 先按helloWorld去查找bean對象,找不到再byType
@Resource
private HelloWorld helloWorld;
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
package com.demo;
import javax.annotation.Resource;
public class HelloWorldService {
//通過byName查找
@Resource(name = "springHelloWorld")
private HelloWorld helloWorld;
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
package com.demo;
import javax.annotation.Resource;
public class HelloWorldService {
//通過byType查找
@Resource(type = HelloWorld.class)
private HelloWorld helloWorld;
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
- @Autowired和@Resource不適合簡單類型的裝配,如int,String等。可以通過@Value來注入,該註解一般與properties文件結合使用,其提了兩種使用方式,SPEL表達式和佔位符,舉例如下。
新建config.properties文件
url=http://10.1.1.1
port=8080
username=Tomandy
password=Tom123
配置bean文件
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<!--基於佔位符方式-->
<bean id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="location" value="config.properties"/>
</bean>
<!--基於SPEL表達式-->
<bean id="configSpel" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>config.properties</value>
</list>
</property>
</bean>
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<bean id="helloWorldService"
class="com.demo.HelloWorldService">
</bean>
</beans>
創建HelloWorldService
package com.demo;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.Resource;
public class HelloWorldService {
@Resource(type = HelloWorld.class)
private HelloWorld helloWorld;
@Value("${url}")
private String url;
@Value("#{configSpel['username']}")
private String userName;
public HelloWorld getHelloWorld() {
System.out.println(this.url);
System.out.println(this.userName);
return helloWorld;
}
}
運行測試類,輸出結果如下
"C:\Program Files (x86)\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\lib\idea_rt.jar=48850:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\github\SpringLearn\target\test-classes;D:\github\SpringLearn\target\classes;C:\Users\lenovo\.m2\repository\org\springframework\spring-core\4.1.4.RELEASE\spring-core-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-context\4.1.4.RELEASE\spring-context-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-aop\4.1.4.RELEASE\spring-aop-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-beans\4.1.4.RELEASE\spring-beans-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-expression\4.1.4.RELEASE\spring-expression-4.1.4.RELEASE.jar" com.demo.TestHelloWorld
三月 01, 2019 6:23:41 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@197848c: startup date [Fri Mar 01 18:23:41 CST 2019]; root of context hierarchy
三月 01, 2019 6:23:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [helloWorldBeans.xml]
三月 01, 2019 6:23:41 下午 org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer loadProperties
信息: Loading properties file from class path resource [config.properties]
三月 01, 2019 6:23:41 下午 org.springframework.beans.factory.config.PropertiesFactoryBean loadProperties
信息: Loading properties file from class path resource [config.properties]
http://10.1.1.1
Tomandy
Spring say Hello!
Process finished with exit code 0
靜態工廠、實例工廠注入
基於工廠注入的方式參考以下文章《spring的五種依賴注入方式》。
@Service及@Repository註解
在bean配置文件加上包掃描路徑,將自動掃描路徑包,如果類帶了@Service註解,將自動註冊到Spring容器,不需要在bean配置文件定義bean了,類似的註解還有@Component、@Repository、@Controller,舉例如下。
配置bean文件,通過使用@Service註解,替換了原先的HelloWorldService的bean配置。
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 聲明包掃描 -->
<context:component-scan base-package="com.demo" />
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
</beans>
創建HelloWorldService
package com.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("helloWorldService")
public class HelloWorldService {
@Autowired
private HelloWorld helloWorld;
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
創建測試類
package com.demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestHelloWorld {
public static void main(String[] args) {
//加載配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("helloWorldBeans.xml");
//spring默認創建是單實例的作用域
HelloWorldService helloWorldService =
(HelloWorldService) context.getBean("helloWorldService");
HelloWorld helloWorld = helloWorldService.getHelloWorld();
helloWorld.sayHello();
}
}
運行測試類,輸出結果爲
"C:\Program Files (x86)\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\lib\idea_rt.jar=52126:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\github\SpringLearn\target\test-classes;D:\github\SpringLearn\target\classes;C:\Users\lenovo\.m2\repository\org\springframework\spring-core\4.1.4.RELEASE\spring-core-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-context\4.1.4.RELEASE\spring-context-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-aop\4.1.4.RELEASE\spring-aop-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-beans\4.1.4.RELEASE\spring-beans-4.1.4.RELEASE.jar;C:\Users\lenovo\.m2\repository\org\springframework\spring-expression\4.1.4.RELEASE\spring-expression-4.1.4.RELEASE.jar" com.demo.TestHelloWorld
三月 01, 2019 7:30:09 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@197848c: startup date [Fri Mar 01 19:30:09 CST 2019]; root of context hierarchy
三月 01, 2019 7:30:09 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [helloWorldBeans.xml]
Spring say Hello!
Process finished with exit code 0