Spring的自动装配(Java学习笔记)

自动装配是什么?

自动装配就是让应用上下文为用户找到依赖项的过程,就是Sping会在上下文中自动查找,并自动给bean装配与其关联的属性。
spring中实现自动装配的方式有两种,一种是xml文件,另有一种是通过注解。

手动装配

通过xml配置文件实现自动装配

我们只需要在bean的配置文件中的bean标签中加入一个属性autowire即可.


使用autowire关键字声明bean的自动装配方式,其可选值为byName,byType,constructor,default,no。

1.byName

设置autowire属性为byName实现进行自动装配,此时spring将会尝试将属性名和bean名称进行匹配,如果找到的话就注入依赖。
autowire=ByName进行自动装配的时候,spring容器将会检查需要注意依赖的bean中依赖名称,当存在依赖的名称时候就会对应得bean注入进去。

//Cat
package org.example;

public class Cat {
}

//Dog
package org.example;

public class Dog {
}

// People
package org.example;

public class People {
    private String name;
    private Cat cat;
    private Dog dog;

    public void getName() {
        System.out.println("People的名字:"+name);
    }

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

    public void getCat() {
        System.out.println("People的猫:"+cat);
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void getDog() {
        System.out.println("People的狗:"+dog);
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }
}

bean,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"           xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="cat" class="org.example.Cat"/>
    <bean id="dog" class="org.example.Dog"/>
    <bean id="people" class="org.example.People">
        <property name="name" value="张三"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean></beans>

运行结果:
在这里插入图片描述
注意:
**需要注意的是:如果spring容器中没有找到对应名称可以注入的bean,将不会向依赖中注入任何bean,此时依赖的bean为null.

2.byType

在byType(类型模式中)spring容器会基于反射查看bean定义的类,然后找到依赖类型相同的bean注入到另外的bean中,这个过程需要setter注入来完成,因此必须存在setter方法,否则就会注入失败

<?xml version="1.0" encoding="UTF-8"?>    <beans xmlns="http://www.springframework.org/schema/beans"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="cat" class="org.example.Cat"/>
    <bean id="dog" class="org.example.Dog"/>
    <bean id="people" class="org.example.People" autowire="byType">
        <property name="name" value="张三"></property>
    </bean>
</beans>

运行结果
在这里插入图片描述
注意:
使用byType这种方式,必须保证配置文件中所有bean的class属性的值是唯一的,否则就会报错

By constructor构造器

使用autowire=constructor的时候,spring容器同样会尝试找到那些类型与构造函数相匹配的bean,然后注入.
autowire=constructor模式下,spring容器会找到类型和构造函数中的类型相匹配的bean,然后注入。
在实际测试开发中当spring容器中出现多个类型和构造函数中的类型相匹配的bean,那么bean的名称和要依赖的名称相同的将会注入进去,会自动将同类不同名的bean过滤掉,如果只有一个bean,类名相同但是名称不同,也会将这个注入到该类中,如果有两个以上bean,类名相同,但是名称不同,这个时候spring容器不知道选择哪一个bean,需要使用autowire-candidate="false"进行过滤。

通过注解实现自动装配

使用注解前的准备

注解是通过反射来实现。
要使用注解,首先要使用如下的文件头:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

注意:
conteext:annotation-config/ 必须要写在xml中,这是用来开启注解的支持,如果不加上注解就无效。

使用

Autowired注解(常用)

然后在实体类的对应属性上添加@Autowired注解(也可以把注解放到对应属性的setter上),people类中依赖Dog类和Cat类。所以在people类中的dog和cat属性上要加上@Autowired,实现自动装配。使用@Autowired注释,可以对成员变量,方法以及构造函数进行标注,完成自动装配的工作。**通过@Autowired的使用标注到成员变量的时候不需要有set方法,Autowired是按照默认类型匹配的.
在使用@Autowired的时候还传递了一个required=fale属性,required属性为false表示userDao实例存在就进行注入不存在的话就忽略,如果required=true,表示必须要进行注入,如果userDao实例不存在就抛出异常。默认情况下@Autowired是按照类型匹配的,如果需要按照名称进行匹配的话,可以使用@Qualifier注解和@Autowired相结合的方式

首先要配置bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="cat02" class="org.example.Cat"/>
    <bean id="dog02" class="org.example.Dog"/>
    <bean id="people02" class="org.example.People02">
        <property name="name" value="张三"/>
    </bean>
</beans>
//people类
package org.example;

import org.springframework.beans.factory.annotation.Autowired;

public class People02 {
    private String name;
    @Autowired(required = false)
//    @Qualifier("cat02")
    private Cat cat;
    @Autowired(required = false)
//    @Qualifier("dog02")
    private Dog dog;

    public void getName() {
        System.out.println("People的name:"+name);
    }

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

    public void getCat() {
        System.out.println("People的Cat:"+cat);
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void getDog() {
        System.out.println("People的Dog:"+dog);
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "People02{" +
                "name='" + name + '\'' +
                ", cat=" + cat +
                ", dog=" + dog +
                '}';
    }
}

运行结果:
在这里插入图片描述

测试代码:

//PeopleTest01
import org.example.People;
import org.example.People02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;

public class PeopleTest01 {
    @Test
    public void Test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
        People people =(People) context.getBean("people");
        people.getName();
        people.getCat();
        people.getDog();
    }
    @Test
    public void Test02(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean04.xml");
        People people = (People) context.getBean("people");
        people.getName();
        people.getCat();
        people.getDog();

    }
    @Test
    public void Test03(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean08.xml");
        People02 people = (People02) context.getBean("people02");
        people.getName();
        people.getCat();
        people.getDog();
        System.out.println(people);
    }
}

Resource

与@Autowired具备相同效果的是@Resource,@Resource默认使用的是byName的方式进行注入,**使用之前要导入Resource包:Package:javax.annotation.Resource,**可以标注在成员变量和set方法上,但是不能放在构造方法上面,@Resource有两个重要的属性:name type ,spring容器会解析@Resource注解的name属性为bean的名字,type属性为bean的类型,使用@Resource注解的name属性表示按照byName进行解析,使用type属性表示按照byType类型进行解析,不指定的时候默认使用name。

Value

@Autowired和@Resource进行自动装配注入的依赖都是对象类型,而不是简单的值类型,之前使用配置文件的setter和构造函数的时候可以通过property属性和constructor-arg属性既可以注入对象类型也可以注入简单值类型,对于这些类型,比如 int boolean long String 等等,spring容器提供了@Value注解的注入方式,@Value注解接收一个String的值,该值指定了要注入到 内置的java类型 的属性值(不用担心类型转换),一般情况下@Value属性和properties文件配合使用,分为两种情况,一种是SpEL(类似于js中的EL表达式),一种是占位符方式.
实例:
bean.xml

<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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!--基于占位符方式 配置单个properties -->
    <!--<context:property-placeholder location="jdbc.properties"/>-->
    <!--基于占位符方式 配置多个properties -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="location" value="jdbc.properties"/>
    </bean>

    <!--基于SpEL表达式 配置多个properties id值为configProperties 提供java代码中使用 -->
    <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>classpath:/jdbc.properties</value>
            </list>
        </property>
    </bean>

    <!--基于SpEL表达式 配置单个properties -->
    <!--<util:properties id="configProperties" location="classpath:jdbc.properties"/>-->

    <!--注解驱动 -->
    <context:annotation-config/>
<bean id="people03" class="org.example.People02" ></bean>
    <bean id="jdbcTest01" class="org.example.JDBCTest01"></bean>
</beans>
//JDBCTest01
package org.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

public class JDBCTest01 {
//    注册成员变量
    @Autowired
    @Qualifier("people03")
    private People02 people;
//    占位符方式
    @Value("${url}")
    private String url;
//    SpEL表达方式
    @Value("#{configProperties['user']}")
    private String username;
    @Value("#{configProperties['password']}")
    private String password;
    @Value("#{configProperties['driver']}")
    private String driver;
    public void done(){
        System.out.println("URL:"+url+"\nUsername:"+username+"\nPassword"+password+"\nDriver:"+driver);
    }
}

测试:

import org.example.JDBCTest01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;

public class ValueTest01 {
    @Test
    public void Test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean09.xml");
        JDBCTest01 jdbcTest01 =(JDBCTest01) context.getBean("jdbcTest01");
        jdbcTest01.done();
    }
}

运行结果:
在这里插入图片描述

学习原文

原文地址1
原文地址2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值