Unit02: 参数值注入 、 基于注解的组件扫描

    Unit02: 参数值注入 、 基于注解的组件扫描    

(4)IOC (Inversion Of Controll 控制反转)

什么是IOC?

对象之间的依赖关系由容器来建立。

什么是DI? (Dependency Injection 依赖注入)

容器通过调用set方法或者构造器来建立对象之间的依赖关系。
注: IOC是目标,而DI是手段。

依赖注入的两种方式

方式一 set方法注入。

step1. 添加set方法。

step2. 配置set方法注入。

方式二 构造器注入。

step1. 添加构造器。

step2. 配置构造器注入。

自动装配 (了解)

什么是自动装配?

容器依据某些规则,自动建立对象之间的依赖关系。
注:默认情况下,容器禁止自动装配。

注入基本类型的值

使用value属性来注入。

注入集合类型的值

List,Set,Map,Properties

引用的方式注入集合类型的值

读取properties文件的内容

使用Spring表达式

案例:

auto

package auto;

public class Restaurant {
    private Waiter wt;
    
    public void setWt(Waiter wt) {
        System.out.println("setWt()");
        this.wt = wt;
    }

    public Restaurant() {
        System.out.println("Restaurant");
    }

    @Override
    public String toString() {
        return "Restaurant [wt=" + wt + "]";
    }

}
Restaurant.java
package auto;

public class Waiter {

    public Waiter() {
        System.out.println("Waiter()");
    }
}
Waiter.java

ioc

package ioc;

public class A {
    private B b;
    
    public A() {
        System.out.println("A()");
    }
    
    public A(B b) {
        System.out.println("A(B)");
        this.b = b;
    }

    public void service(){
        System.out.println("A's service()");
        b.f1();
    }
    
}
A.java
package ioc;

public class B {

    public B() {
        System.out.println("B()");
    }
    
    public void f1(){
        System.out.println("B's f1()");
    }
    
}
B.java

value

package value;

public class SpelBean {
    private String name;
    private String interest;
    private double score;
    private int pageSize;
    
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public SpelBean() {
        System.out.println("SpelBean");
    }

    public void setScore(double score) {
        this.score = score;
    }

    public void setInterest(String interest) {
        this.interest = interest;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "SpelBean [name=" + name + ", interest=" + interest + ", score=" + score + ", pageSize=" + pageSize
                + "]";
    }
    
    
    
}
SpelBean.java
package value;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class ValueBean {
    private String name;
    private int age;
    private List<String> interest;
    private Set<String> city;
    private Map<String,Double> score;
    private Properties db;
    
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public List<String> getInterest() {
        return interest;
    }
    public Set<String> getCity() {
        return city;
    }
    public Map<String, Double> getScore() {
        return score;
    }
    public Properties getDb() {
        return db;
    }
    public void setInterest(List<String> interest) {
        this.interest = interest;
    }
    public void setDb(Properties db) {
        this.db = db;
    }
    public void setCity(Set<String> city) {
        this.city = city;
    }
    public void setScore(Map<String, Double> score) {
        this.score = score;
    }
    public ValueBean() {
        System.out.println("ValueBean()");
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "ValueBean [name=" + name + ", age=" + age + ", interest=" + interest + ", city=" + city + ", score="
                + score + ", db=" + db + "]";
    }
    
    
}
ValueBean.java

src/main/resource

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <bean id="wt2" class="auto.Waiter"/>
    <!-- 
        autowire指定自动装配的规则,有这样三个值:
        byName: 容器依据属性名查找对应的bean(即
        bean的id等于属性名),找到之后,调用对应的
        set方法来完成注入。
            注:如果找不到,会注入null值。
        byType:容器依据属性类型查找对应的bean(即
        bean的类型与属性类型一致),找到之后,调用对
        应的set方法来完成注入。
            注:如果找不到,会注入null值。
                如果找到多个,会出错。
        constructor:类似byType,只不过会调用构造器
        来完成注入。
     -->
    <bean id="rest" class="auto.Restaurant" 
    autowire="byType"/>
</beans>
auto.xml
pagesize=10
config.properties
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <bean id="b1" class="ioc.B"/>
    <!--
        构造器方式注入。
        index属性:指定参数的下标(从0开始) 
     -->
    <bean id="a1" class="ioc.A">
        <constructor-arg index="0" ref="b1"/>
    </bean>
    
</beans>
ioc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <!-- 
        使用Spring表达式读取其它bean的属性值。
     -->
    <bean id="sb1" class="value.SpelBean">
        <property name="name" 
        value="#{vb1.name}"/>
        <property name="interest"
        value="#{vb1.interest[0]}"/>
        <property name="score"
        value="#{vb1.score['英语']}"/>
        <property name="pageSize"
        value="#{config.pagesize}"/>
    </bean>
    
    <bean id="vb1" class="value.ValueBean">
        <property name="name" value="小月"/>
        <property name="age" value="22"/>
        <property name="interest">
            <list>
                <value>钓鱼</value>
                <value>旅游</value>
                <value>看电视</value>
                <value>看电视</value>
            </list>
        </property>
        <property name="city">
            <set>
                <value>北京</value>
                <value>长沙</value> 
                <value>南京</value>
            </set>
        </property>
        <property name="score">
            <map>
                <entry key="英语" value="60"/>
                <entry key="math" value="80"/>
            </map>
        </property>
        <property name="db">
            <props>
                <prop key="username">King</prop>
                <prop key="password">1234</prop>
            </props>
        </property>
    </bean>
    
    <!-- 引用的方式注入集合类型的值 -->
    <util:list id="interestBean">
        <value>钓鱼</value>
        <value>旅游</value>
        <value>上网</value>
    </util:list>
    <util:set id="cityBean">
        <value>北京</value>
        <value>上海</value>
        <value>武汉</value>
    </util:set>
    <util:map id="scoreBean">
        <entry key="english" value="80"/>
        <entry key="math" value="90"/>
    </util:map>
    <util:properties id="dbBean">
        <prop key="username">King</prop>
        <prop key="password">1234</prop>
    </util:properties>
    <bean id="vb2" class="value.ValueBean">
        <property name="interest" 
        ref="interestBean"/>
        <property name="city"
        ref="cityBean"/>
        <property name="score"
        ref="scoreBean"/>
        <property name="db"
        ref="dbBean"/>
    </bean>
    
    <!-- 读取properties文件的内容 -->
    <!-- 
        location属性:指定要 读取的文件的位置,
        其中,classpath:表示依据类路径去查找。
     -->
    <util:properties id="config" 
    location="classpath:config.properties"/>
    
    
    
</beans>
value.xml

src/test/java

test

package test;

import java.util.Properties;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import auto.Restaurant;
import ioc.A;
import value.SpelBean;
import value.ValueBean;

public class TestCase {
    @Test
    // 测试 构造器方式的注入
    public void test1() {
        // 启动Spring容器
        String config = "ioc.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 获得对象
        A a1 = ac.getBean("a1", A.class);
        a1.service();
    }

    @Test
    // 测试 自动装配
    public void test2() {
        // 启动Spring容器
        String config = "auto.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 获得对象
        Restaurant rest = ac.getBean("rest", Restaurant.class);
        System.out.println(rest);
    }

    @Test
    // 测试 注入基本类型的值
    public void test3() {
        // 启动Spring容器
        String config = "value.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        ValueBean vb1 = ac.getBean("vb2", ValueBean.class);
        System.out.println(vb1);
    }

    @Test
    // 读取properties文件
    public void test4() {
        // 启动Spring容器
        String config = "value.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        Properties props = ac.getBean("config", Properties.class);
        System.out.println(props);
    }

    @Test
    // 测试 Spring表达式
    public void test5() {
        // 启动Spring容器
        String config = "value.xml";
        ApplicationContext ac =
            new ClassPathXmlApplicationContext(
                    config);
        SpelBean sb1 = 
                ac.getBean("sb1",SpelBean.class);
        System.out.println(sb1);
    }
}
TestCase.java

    使用注解简化配置    

(1)什么是组件扫描?

Spring容器会扫描base-package指定的包及其子包下面的所有的类, 如果这些类前面有一些特殊的注解(比如@Component),则Spring 容器会将这些类纳入容器进行管理(相当于在配置文件当中有对应的bean)。

(2)如何进行组件扫描?

step1. 在类前面添加特定的注解。比如 @Component。

 

step2. 在配置文件当中,配置组件扫描。

(3)作用域和延迟加载相关注解

(4)依赖注入相关的注解

(5)value注解

案例:

annotation

package annotation;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("eb")
public class ExampleBean {
    @Value("小月")
    private String name;
    
    @Value("#{config.pagesize}")
    private int pageSize;
    
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public ExampleBean() {
        System.out.println("ExampleBean()");
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "ExampleBean [name=" + name + ", pageSize=" + pageSize + "]";
    }
    
    
    
}
ExampleBean.java
package annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component("mg")
public class Manager {
    private Waiter wt;
    
    public Manager() {
        System.out.println("Manager()");
    }
    
    @Autowired
    public Manager(@Qualifier("wt") Waiter wt) {
        System.out.println("Manager(wt)");
        this.wt = wt;
    }

    @Override
    public String toString() {
        return "Manager [wt=" + wt + "]";
    }
    
    
    
}
Manager.java
package annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component("rest")
public class Restaurant {
    
    @Autowired
    @Qualifier("wt")
    private Waiter wt;
    
//    @Autowired
//    public void setWt(@Qualifier("wt") Waiter wt) {
//        System.out.println("setWt()");
//        this.wt = wt;
//    }

    @Override
    public String toString() {
        return "Restaurant [wt=" + wt + "]";
    }

    public Restaurant() {
        System.out.println("Restaurant()");
    }
    
}
Restaurant.java
package annotation;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

@Component("school")
public class School {
    
    private Waiter wt;
    
    @Resource(name="wt")
    public void setWt(Waiter wt) {
        System.out.println("setWt()");
        this.wt = wt;
    }

    public School() {
        System.out.println("School()");
    }

    @Override
    public String toString() {
        return "School [wt=" + wt + "]";
    }
    
}
School.java
package annotation;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("stu1")
@Scope("singleton")
@Lazy(true)
public class Student {

    public Student() {
        System.out.println("Student()");
    }
    
    @PostConstruct
    public void init(){
        System.out.println("init()");
    }
    
    @PreDestroy
    public void destroy(){
        System.out.println("destroy()");
    }
    
}
Student.java
package annotation;

import org.springframework.stereotype.Component;

@Component("wt")
public class Waiter {

    public Waiter() {
        System.out.println("Waiter()");
    }
    
}
Waiter.java

src/main/resources

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <!-- 配置组件扫描 -->
    <!-- 
        Spring容器会扫描base-package指定的包及
        其子包下面的所有的类,如果这些类前面有一
        些特殊的注解(比如@Component),则Spring
        容器会将这些类纳入容器进行管理(相当于在
        配置文件当中有对应的bean)。
     -->
    <context:component-scan 
        base-package="annotation"/>
    
    <util:properties id="config" 
    location="classpath:config.properties"/>
    
    
</beans>
annotation.xml
pagesize=10
config.properties

src/test/java

test

package test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import annotation.ExampleBean;
import annotation.Manager;
import annotation.Restaurant;
import annotation.School;
import annotation.Student;

public class TestCase {
    @Test
    //测试 组件扫描
    public void test1(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);
        Student stu1 = 
                ac.getBean("stu1",
                        Student.class);
        System.out.println(stu1);
    }
    
    @Test
    //测试 作用域
    public void test2(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);
        Student stu1 = 
                ac.getBean("stu1",
                        Student.class);
        Student stu2 = 
                ac.getBean("stu1",
                        Student.class);
        System.out.println(stu1 == stu2);
    }
    
    @Test
    // 测试 生命周期
    public void test3(){
        String config = "annotation.xml";
        AbstractApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);    
        Student stu1 = 
                ac.getBean("stu1",
                        Student.class);
        ac.close();
    }
    
    @Test
    // 测试 延迟加载
    public void test4(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);    
    }
    
    @Test
    // 测试 @Autowired和 @Qualifier
    public void test5(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);
        Restaurant rest = 
            ac.getBean("rest",Restaurant.class);
        System.out.println(rest);
        
        Manager mg = 
                ac.getBean("mg",Manager.class);
        System.out.println(mg);
    }
    
    @Test
    //测试 @Resource
    public void test6(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);
        School s = 
                ac.getBean("school",
                        School.class);
        System.out.println(s);
    }
    
    @Test
    //测试 @Value
    public void test7(){
        String config = "annotation.xml";
        ApplicationContext ac = 
        new ClassPathXmlApplicationContext(
                config);
        ExampleBean eb = 
            ac.getBean("eb",ExampleBean.class);
        System.out.println(eb);
    }

}
TestCase.java
原文地址:https://www.cnblogs.com/tangshengwei/p/6487081.html