前言
對于傳統(tǒng)的應(yīng)用程序,一般通過new object()來創(chuàng)建對象躲胳,主動(dòng)權(quán)和創(chuàng)建時(shí)機(jī)由自己把控闸溃,而IOC意味著將創(chuàng)建和查找依賴對象的控制權(quán)交給了容器,由容器進(jìn)行注入組合對象疹鳄。對象的獲取由主動(dòng)變?yōu)楸粍?dòng),這就是IOC控制反轉(zhuǎn)的設(shè)計(jì)思想芦岂。
快速入門
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>
代碼示例
創(chuàng)建HelloWorld接口
package com.demo;
public interface HelloWorld {
void sayHello();
}
創(chuàng)建接口實(shí)現(xiàn)類
package com.demo;
public class SpringHelloWorld implements HelloWorld {
public void sayHello() {
System.out.println("Spring say Hello!");
}
}
創(chuàng)建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指向創(chuàng)建的對象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創(chuàng)建 -->
<bean id="springHelloWorld"
class="com.demo.SpringHelloWorld"></bean>
<!-- 聲明helloWorldService對象,由spring創(chuàng)建 -->
<bean id="helloWorldService"
class="com.demo.HelloWorldService">
<!--注入springHelloWorld對象,需要setHelloWorld方法-->
<property name="helloWorld" ref="springHelloWorld"/>
<!--注入name變量值懦趋,需要setName方法-->
<property name="name" value="Tomandy"/>
</bean>
</beans>
創(chuàng)建測試類
package com.demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestHelloWorld {
public static void main(String[] args) {
//加載配置文件晾虑,默認(rèn)查找classpath路徑下的文件
ApplicationContext context =
new ClassPathXmlApplicationContext("helloWorldBeans.xml");
//spring默認(rèn)創(chuàng)建是單實(shí)例的作用域
HelloWorldService helloWorldService =
(HelloWorldService) context.getBean("helloWorldService");
HelloWorld helloWorld = helloWorldService.getHelloWorld();
helloWorld.sayHello();
}
}
運(yùn)行測試類,輸出結(jié)果為
"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可以幫助我們創(chuàng)建對象springHelloWorld惑芭,并注入helloWorldService中坠狡,上述代碼使用的setter注入方式,還可以通過構(gòu)造函數(shù)遂跟、注解逃沿、靜態(tài)工廠婴渡、實(shí)例工廠來注入,下面文章再說明凯亮。
除了通過ClassPathXmlApplicationContext去加載spring的配置文件边臼,還可以通過FileSystemXmlApplicationContext去加載,區(qū)別在于前者默認(rèn)查找classpath路徑下的文件假消,后者默認(rèn)查找項(xiàng)目工作路徑柠并,即項(xiàng)目的根目錄,文章《關(guān)于Spring IOC (DI-依賴注入)你需要知道的一切》舉例如下富拗。
//默認(rèn)查找classpath路徑下的文件
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml");
//多文件,也可傳遞數(shù)組
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml","spring/spring-ioc2.xml",.....);
//默認(rèn)為項(xiàng)目工作路徑 即項(xiàng)目的根目錄
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的自動(dòng)裝配
上述例子bean文件配置了property屬性臼予,實(shí)際屬于手工裝配,spring也提供了自動(dòng)裝配的方式啃沪,分別有byName,byType,constructor三種方式粘拾,下面通過舉例來說明他們之間的區(qū)別。
- byName创千,顧名思義就是按照名稱匹配缰雇。根據(jù)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>
創(chuàng)建HelloWorldService
package com.demo;
public class HelloWorldService {
private HelloWorld helloWorld;
public void setHelloWorld(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
byName模式會(huì)根據(jù)beanid helloWorld去和setHelloWorld方法的后半部分名稱(HelloWorld)比對氯檐,如果(首字母轉(zhuǎn)換為大寫)一致則注入成功戒良。
- byType体捏,即按照類型匹配冠摄。Spring容器會(huì)基于反射查看bean定義的類,然后找到與set方法參數(shù)類型相同的bean來注入几缭,需要通過set方法來實(shí)現(xiàn)河泳。
配置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>
創(chuàng)建HelloWorldService
package com.demo;
public class HelloWorldService {
private HelloWorld helloWorld;
public void setHelloWorld(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
public HelloWorld getHelloWorld() {
return helloWorld;
}
}
運(yùn)行測試類拆挥,輸出結(jié)果為
Spring say Hello!
當(dāng)存在多個(gè)相同類型的bean時(shí),使用byType方式會(huì)報(bào)錯(cuò)某抓,此時(shí)可以通過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容器同樣會(huì)嘗試找到那些類型與構(gòu)造函數(shù)相同匹配的bean注入否副。當(dāng)存在多個(gè)類型相同bean時(shí)汉矿,按名稱優(yōu)先匹配,如果沒有找到對應(yīng)名稱备禀,則注入失敗洲拇,此時(shí)可以使用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/>
<!--如果存在多個(gè)相同類型的,則按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注入赋续,還可以通過構(gòu)造函數(shù)男翰、注解、靜態(tài)工廠纽乱、實(shí)例工廠注入蛾绎。
構(gòu)造函數(shù)注入
spring容器會(huì)根據(jù)bean中指定的構(gòu)造函數(shù)參數(shù)來決定調(diào)用那個(gè)構(gòu)造函數(shù)。
創(chuàng)建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 + "個(gè)列表值:" + 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>
運(yùn)行測試后秘通,輸出結(jié)果如下。
"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個(gè)列表值:tom1
第1個(gè)列表值:tom2
key為:key1 value為:value1
key為:key2 value為:value2
Spring say Hello!
Process finished with exit code 0
注解注入
需在bean文件加上以下內(nèi)容敛熬,注解注入才生效肺稀。
<context:annotation-config />
- 可以通過@Autowired對成員變量、set方法应民、構(gòu)造函數(shù)進(jìn)行標(biāo)注來實(shí)現(xiàn)依賴注入话原,該注解默認(rèn)按byType匹配,如果需要按byName匹配诲锹,可以通過@Qualifier來指定對象的名稱繁仁,指定的名稱需與bean文件的對象名稱一致,否則會(huì)報(bào)錯(cuò)归园。
創(chuàng)建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>
運(yùn)行測試類黄虱,輸出結(jié)果如下。
"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
通過以上例子可發(fā)現(xiàn)庸诱,通過標(biāo)注成員變量捻浦,可以省略set方法和構(gòu)造函數(shù),大大簡化了代碼桥爽。
- @Resource的功能與@Autowired類似朱灿,但不能標(biāo)注構(gòu)造函數(shù)。默認(rèn)按照byName進(jìn)行裝配钠四,名稱可以通過name屬性進(jìn)行指定盗扒,如果沒有指定name屬性,當(dāng)注解寫在成員變量上時(shí)缀去,默認(rèn)取成員變量名進(jìn)行byName查找侣灶,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。 當(dāng)找不到與名稱匹配的bean時(shí)才按照byType進(jìn)行裝配缕碎。
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文件結(jié)合使用,其提了兩種使用方式栅贴,SPEL表達(dá)式和占位符斟湃,舉例如下。
新建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表達(dá)式-->
<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>
創(chuàng)建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;
}
}
運(yùn)行測試類檐薯,輸出結(jié)果如下
"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
靜態(tài)工廠凝赛、實(shí)例工廠注入
基于工廠注入的方式參考以下文章《spring的五種依賴注入方式》。
@Service及@Repository注解
在bean配置文件加上包掃描路徑坛缕,將自動(dòng)掃描路徑包墓猎,如果類帶了@Service注解,將自動(dòng)注冊到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>
創(chuàng)建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;
}
}
創(chuàng)建測試類
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默認(rèn)創(chuàng)建是單實(shí)例的作用域
HelloWorldService helloWorldService =
(HelloWorldService) context.getBean("helloWorldService");
HelloWorld helloWorld = helloWorldService.getHelloWorld();
helloWorld.sayHello();
}
}
運(yùn)行測試類俭嘁,輸出結(jié)果為
"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