自动装配与纯注解式自动装配依赖注入

自动装配与注解实现自动装配

自动装配:

autowire:

public class Rule {
    public void moval(){
        System.out.println("橡皮叫");
    }
}
public class Pen {
    public void write(){
        System.out.println("钢笔叫");
    }
}
public class Teach {
    private Rule rule;
    private Pen pen;
    public void setPen(Pen pen) {
        this.pen = pen;
    }
    public void setRule(Rule rule){
        this.rule=rule;
    }
    public Rule getRule() {
        return rule;
    }
    public Pen getPen() {
        return pen;
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("Bean.xml");
        Teach teach=(Teach) applicationContext.getBean("teach");
        teach.getRule().moval();
        teach.getPen().write();
    }
}

> byName的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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="pen" class="Pen"></bean>
    <bean id="rule" class="Rule"></bean>

    <bean id="teach" class="Teach" autowire="byName" >
    </bean>
</beans>

结果:

橡皮叫
钢笔叫

关于byName总结:
1、byName:会自动寻找当前对象中的set方法,识别set方法后面的字符串,例如Teach中有setpen,配置文件就会寻找在配置文件中 id 为pen的对象,注意大小写

2、id必须唯一

> byType的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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="pen" class="Pen"></bean>
    <bean id="rule" class="Rule"></bean>
    <bean id="teach" class="Teach" autowire="byType" ></bean>
</beans>

byType只看class,所以可以没有id

 <bean class="Pen"></bean>
    <bean class="Rule"></bean>

关于bytype总结:
class必须是唯一的
byType:寻找自己对象(teach)中属性和其他注册的Bean中一样的class

byName和byType都是代替了原本配置文件中的<property XXX/>,(用于应用类注入:实体类中的成员属性名称不是id,bean等,如:已知接口face和其实现类Dao,则private face dao;其中dao 没什么含义,就是随便起的名),两者都不适用于简单类型注入,因为,要赋值,那么你的这两种方法怎么赋值呢,都是根据配置文件中的id和class来判断的

注解自动装配:

@Autowired

@Autowired是默认按照byType实现的,对象必须存在
@Autowired可以放在属性,这时可以不加set方法,因为注释@Autowired是通过反射来实现注入的(前提:自动装配的这个属性一定是在容器中存在,并且满足byType,(就是容器中的类型与自动装配中的属性所指的对象相同)
@Autowired也可以放在set方法
当两个实体类同时实现同一个抽象方法时,需要使用到@Qualifier来指定id,详情往下翻
@Autowired在类中的引用属性上,会在当前类用到这个属性时,去容器里面查找相同类型的bean,然后拿来用相当于<property ></property>

imp.ort org.springframework.beans.factory.annotation.Autowired;

public class Teach {
    @Autowired
    private Rule rule;
    @Autowired
    private Pen pen;

    public void setPen(Pen pen) {
        this.pen = pen;
    }
    public void setRule(Rule rule){
        this.rule=rule;
    }
    public Rule getRule() {
        return rule;
    }
    public Pen getPen() {
        return pen;
    }
}

注解实现自动装配时的配置文件:

配置文件中加入相关的约束,例如:
1、xmlns:context=“http://www.springframework.org/schema/context”
2、 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
3、<context:annotation-config/>

<?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
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd">
          <!--开启注解的支持-->
<context:annotation-config/>
    <bean id="pen" class="Pen"></bean>
    <bean id="rule111" class="Rule"></bean>
    <bean id="teach" class="Teach" ></bean>
</beans>

除此之外,还有纯注解型,多添加一个配置类,其余没有大变化:@Configuration:表示注解类,@CompoenetScan:表示要扫描的包

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"cxjit","itjh"})
public class Config{
}

测试:

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

public class TestSpring {
    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("Bean.xml");
        Teach teach=(Teach) applicationContext.getBean("teach");
        teach.getRule().moval();
        teach.getPen().write();
    }
}

有了@Autowired之后,就不需要在配置文件中配置相关的属性注入(注解就等同于autowire="byType/byName" )注解默认的类型是byType,容器会根据注解自动寻找到需要注入的属性

有时需要允许注入的对象为空
1、就可以使用@Aurowired中的一个属性require

 @Autowired(require=false)
    private Rule rule;

2、或者利用@Nullable标记字段

public Teach(@Nullable Rule rule){
	this.rule=rule;
}

注:
@Autowired还可以与@Qualifier连用(当实体类中的成员变量为引用类型时,如:private Face face Face为一个接口,而有两个类都实现Face)
@Qualifier(必须与@Autowired连用,无法单独使用):

    @Autowired
    @Qualifier(value = "rule111")//@Qualifier("rule111")
    private Rule rule;

这里的 @Qualifier(value = “rule111”)意为: 指定寻找配置文件中id为“rule111”的Bean,如下:

@Component("rule111")
public class Rule {
    public void moval(){
        System.out.println("橡皮叫");
    }
}

类似于Autowired的注解还有很多,例如:@Resource

Resource是默认按照Bean的名称来装配的,也就是byName,名称找不到时(多个Bean名称相同时)就通过Bean的类型来装配,也就是byType

写在属性上面,并且也可以指定一个配置文件中的id,例如:

@Resource(name="pen")//意思就是指定配置文件
					//中id为cat的对象
 private Pen pen;					

-----------------------------------------------------------------------------------------------------------------

自动装配和注解实现自动装配
1、自动装配就是在配置文件中加入autowire="byType/byName" 代替了<property XXX/>
2、注解实现自动装配就是在各个类中添加注解,代替了autowire="byType/byName"这种在配置文件中的自动装配配置

-----------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------
上面举的例子是引用类型,当然简单类型也可以进行注解: @Value
实体类: @Value(“motherfuck!”)可以放在成员变量上(会自动用构造器注入),也可以放在setter方法上(会set注入),也可以没有setter方法,但是成员变量需一直存在

@Component
public class Fac6 {
    @Value("motherfuck!")
    private String name;

    public void setName(String name1){
        this.name=name1;
        System.out.println("baby");
    }
    public String getName(){
        return name;
    }
}

纯注解式下的配置类:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;


@Configuration
@ComponentScan({"cxjit","itjh",})
public class Config{
}

测试类与上面例子的测试类一种想法
-----------------------------------------------------------------------------------------------------------------

但是,这种方式注入的name的值,是写死的,于是应当搭配properties文件食用,效果更佳!

先创建一个properties文件:

name="motherfuck!"

调整下配置类:添加@PropertySource("classpath:jdbc.properties")

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;


@Configuration
@ComponentScan({"cxjit","itjh",})
@PropertySource("classpath:jdbc.properties")
public class Config{
}

实体类:将@Value写成@Value(“${name}”)

package cxjit;

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

@Component
public class Fac6 {
    @Value("${name}")
    private String name;

    public void setName(String name1){
        this.name=name1;
        System.out.println("baby");
    }
    public String getName(){
        return name;
    }
}

于是,下次只需要改变properties文件就可以改变数值

测试类:

import cxjit.Fac6;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestDay04 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(Config.class);
        Fac6 fac6=(Fac6) annotationConfigApplicationContext.getBean("fac6");
        System.out.println(fac6.getName());
    }
}

结果:

motherfuck!

过程:配置类充当配置文件,加入并用@PropertySource注解来链接properties文件中的name=motherfuck!,然后在实体类中加注解@Value("${name}"),于是测试类调用时,就会根据@Value注解中的name找到properties文件里的name

注意: @PropertySource一定程度上充当了配置文件时的location="jdbc.properties",但是有些情况,他不能完全如他爹一样,如*.jproperties(加载所有的properties文件),有星号 他会报错,认为星号是一个文件名,而咱又没有创建过这个文件名,请点击:properties文件相关知识

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值