spring依赖注入2、注解概述

本文详细介绍Spring框架中的依赖注入技术,包括构造器注入、自动装配、基本类型与集合类型的注入等多种方式,并介绍了如何利用注解简化配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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");
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值