自动装配与注解实现自动装配
自动装配:
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文件相关知识