首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

(三)测试学习JavaWeb之Spring IOC

2024-12-19 来源:化拓教育网

前言

对于传统的应用程序,一般通过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

参考资料

显示全文