前言
对于传统的应用程序,一般通过new object()来创建对象,主动权和创建时机由自己把控,而IOC意味着将创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象。对象的获取由主动变为被动,这就是IOC控制反转的设计思想。
IOC
快速入门
项目工程pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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 -->
<!-- -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 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
<!--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
//默认查找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
<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
<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
<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
<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
<!--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
<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
<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
静态工厂、实例工厂注入
@Service及@Repository注解
在bean配置文件加上包扫描路径,将自动扫描路径包,如果类带了@Service注解,将自动注册到Spring容器,不需要在bean配置文件定义bean了,类似的注解还有@Component、@Repository、@Controller,举例如下。
配置bean文件,通过使用@Service注解,替换了原先的HelloWorldService的bean配置。
<beans
<!-- 声明包扫描 -->
<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