spring依赖注入2、注解概述

来源:互联网 发布:学说四川话的软件 编辑:程序博客网 时间:2024/06/06 17:17

4.构造器方式注入

  • step1. 添加构造器方法.
  • step2. 配置constructor-arg 元素

    • index属性:指定参数的下标
    • ref属性:指被传进来的bean的ID
  • 类A

package ioc;public class A {    private B b;    public A(B b) {        System.out.println("A(B)");        this.b = b;    }    public A() {        System.out.println("A()");    }    public void execute() {        System.out.println("execute()");        b.f1();    }}
  • 类B
package ioc;public class B {    public B() {        System.out.println("B()");    }    public void f1() {        System.out.println("B's f1()");    }}
  • Test
@Test    //测试构造器方式注入    public void test1() {        ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");        A a1 = ac.getBean("a1",A.class);        a1.execute();    }
  • xml文件
<!--     constructor-arg元素:配置构造器方式注入    index属性:指定参数的下标(从0开始)    ref属性:指被传进来的bean的ID --><bean id="b1" class="ioc.B"></bean><bean id="a1" class="ioc.A">    <constructor-arg index="0" ref="b1">    </constructor-arg></bean>

5.自动装配

  • 自动装配,指的是spring容器依据某种规则,自动建立对象之间的依赖关系.
  • 注意:

    1. 默认情况下,容器不会自动装配.
    2. 可以通过指定autowire(自动装配)属性,进行自动装配.容器仍然需要通过调用set/构造器来完成依赖关系的建立.
    3. 自动装配优先使用byName.
  • 类restaurant

package ioc;public class Restaurant {    private Waiter wt;    public Restaurant() {        System.out.println("Restaurant()");    }    public void setWt(Waiter wt) {        System.out.println("setWt()");        this.wt = wt;    }    @Override    public String toString() {        return "Restaurant [wt=" + wt + "]";    }}
  • 类writer
package ioc;public class Waiter {    public Waiter() {        System.out.println("Waiter()");    }}
  • xml文件
<bean id="wt1" class="ioc.Waiter"></bean>     <!--         autowire属性:表示让容器自动装配,如果值为        注意:        byName:        byName:容器依据属性名查找对应的bean,然后调用对应的set方法来完成注入            1.如果找不到对应的bean,则会注入null.            2.不可能找到多个符合条件的bean.        byType:            容器依据属性类型查找对应bean,然后调用对应的set方法来完城注入.        注意:            1.找不到仍然注入空值            2.有可能找到多个符合条件的bean会出错.        constructor:            与byType类似,不同的是调用对应的构造器来注入.      -->     <bean id="rest" class="ioc.Restaurant" autowire="byType"></bean>
  • @test
@Test    //测试自动装配    public void test2() {        ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");        Restaurant rest = ac.getBean("rest",Restaurant.class);        System.out.println(rest);    }

6.注入基本类型的值

  • 使用value属性

7.注入集合类型的值

  • List Set Map Properties

  • 测试类

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> city;    private Set<String> interest;    private Map<String,  Integer> source;    private Properties db;    public void setDb(Properties db) {        this.db = db;    }    public void setSource(Map<String, Integer> source) {        this.source = source;    }    public void setInterest(Set<String> interest) {        this.interest = interest;    }    public void setCity(List<String> city) {        this.city = city;    }    public void setName(String name) {        this.name = name;    }    public void setAge(int age) {        this.age = age;    }    public ValueBean() {        System.out.println("ValueBean()");    }    @Override    public String toString() {        return "ValueBean [name=" + name + ", age=" + age + ","                + " city=" + city + ", interest=" + interest + ", source="                + source + ", db=" + db + "]";    }}
  • xml文件
<bean id="vb1" class="value.ValueBean">        <property name="name" value="张三"></property>        <property name="age" value="23"></property>        <property name="city">            <list>                <value>北京</value>                <value>上海</value>                <value>广州</value>            </list>        </property>        <property name="interest">            <set>                <value>唱歌</value>                <value>跳舞</value>                <value>学习</value>            </set>        </property>        <property name="source">            <map>                <entry key="语文" value="98"></entry>                <entry key="数学" value="99"></entry>                <entry key="英语" value="88"></entry>            </map>        </property>        <property name="db">            <props>                <prop key="username">scott</prop>                <prop key="password">tiger</prop>                <prop key="drivar">oracle.jdbc.OracleDriver</prop>                <prop key="url">jdbc:oracle:thin:@192.168.56.101:1521:orcl</prop>            </props>        </property>    </bean>
  • @Test
@Test    //测试基本类型值得注入    public void test3() {        ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");        ValueBean vb = ac.getBean("vb1",ValueBean.class);        System.out.println(vb);    }
  • 输出
ValueBean()ValueBean [name=张三, age=23, city=[北京, 上海, 广州], interest=[唱歌, 跳舞, 学习], source={语文=98, 数学=99, 英语=88}, db={url=jdbc:oracle:thin:@192.168.56.101:1521:orcl, password=tiger, drivar=oracle.jdbc.OracleDriver, username=scott}]

8.引用方式注入集合的值

  • 示例代码
    <!-- 将集合类型的值配置成一个bean -->    <util:list id="cityBean">        <value>丽江</value>        <value>桂林</value>        <value>云南</value>    </util:list>    <util:set id="interestBean">        <value>书法</value>        <value>绘画</value>        <value>拳击</value>    </util:set>    <util:map id="sourceBean">        <entry key="政治" value="99"></entry>        <entry key="历史" value="78"></entry>        <entry key="地理" value="79"></entry>    </util:map>    <util:properties id="dbBean">        <prop key="username">hr</prop>        <prop key="password">h1</prop>    </util:properties>    <!-- 引用的方法注入集合类型的值 -->    <bean id="vb2" class="value.ValueBean">        <property name="city" ref="cityBean"></property>            <property name="interest" ref="interestBean"></property>        <property name="source" ref="sourceBean"></property>        <property name="db" ref="dbBean"></property>        <property name="name" value="李四"></property>        <property name="age" value="26"></property>    </bean>

9.读取properties文件的内容

  • 示例代码
    <!-- 读取properties问文件的内容        classpath:表示按照类路径来搜索.        spring容器会依据这个路径找到对应的配置文件,然后 读取内容到properties对象      -->     <util:properties id="config" location="classpath:config.properties"/>   

10.使用spring表达式

  • xml文件
    <!-- spring表达式用来读取其他bean的属性值 -->    <bean id="sp1" class="value.SpelBean">        <property name="name" value="#{vb1.name}"/>        <property name="city" value="#{vb1.city[0]}"/>        <property name="score" value="#{vb1.source['语文']}"/>        <property name="pageSize" value="#{config.pagesize}"></property>    </bean>

vb1是bean的id,name是属性名

使用注解简化配置

1.组件扫描

  • 概述:指的是Spring容器在启动之后,会扫描指定的包及其子包下面的所有的类,如果该类前面有特定的注解(比如@Component),则Spring容器会将其这个类纳入容器进行管理.

2.如何进行组件扫描

  • step1:添加注解
package annotation;import org.springframework.stereotype.Component;/* * 注解:Component * sb1 是bean的id,它的缺省值是类名首字母小写之后的类名. */@Component("sb1")//组件public class SomeBean {    public SomeBean() {        System.out.println("SomeBean()");    }}
  • 注解标记

    1. @Component(Spring框架提供) 通用注解
    2. @Repository 持久化层组件注解
    3. @Service 业务层组件注解
    4. @Controller 控制层组件注解
  • 作用是等价的,可用通用,只不过有语义上的差异

  • step2:在配置文件当中添加组件扫描的配置

    <!-- 配置组件扫描 -->    <!--         base-package属性:指定要扫描的包名,spring容器会扫描该包及其子包下面的所有的类,如果前面有特定的注解        (比如:@Component),则spring容器会将其纳入容器进行管理(相当于配置了一个bean元素)     -->    <context:component-scan base-package="annotation"/>

3.作用标记

  • @Scope()
  • @Component(“sb1”)
  • @Lazy(true)
  • @PostConstruct
  • @PreDestroy
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 * sb1是bean的id,它的缺省值是类名首字母小写之后的类名. *///@Scope("prototype")//指定作用域@Component("sb1")    //通用注解@Scope("singleton")  //单例模式.默认的@Lazy(true)          //表示延迟加载//组件public class SomeBean {    //表示初始化注解    @PostConstruct    public void init() {        System.out.println("init()");    }    //表示销毁之前,需要把作用改成单例,因为原型不起作用    @PreDestroy    public void destroy() {        System.out.println("destroy");    }    public SomeBean() {        System.out.println("SomeBean()");    }}
  • @Test
@Test    //测试注解    public void test8() {        ApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");        SomeBean sb1 = ac.getBean("sb1",SomeBean.class);        System.out.println(sb1);    }    @Test    //测试作用域    public void test9() {        ApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");        SomeBean sb1 = ac.getBean("sb1",SomeBean.class);        SomeBean sb2 = ac.getBean("sb1",SomeBean.class);        System.out.println(sb1 == sb2);    }    @Test    //测试生命周期相关的方法    public void test10() {        AbstractApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");        SomeBean sb1 = ac.getBean("sb1",SomeBean.class);        ac.close();    }    @Test    //测试延迟加载    public void test11() {        ApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");    }