Spring 框架学习---- bean自动装配注解开发
Posted RAIN 7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 框架学习---- bean自动装配注解开发相关的知识,希望对你有一定的参考价值。
文章目录
- Spring 框架学习(七)---- bean自动装配、注解开发
- 一、Bean的自动装配
- 1、在xml中显式的配置
- 2、隐式的自动装配【重要】
- 3、Java中显式配置
- 二 、使用注解开发
- 1、注册bean的注解
- 2、衍生的注解
- 3、自动装配的注解
- 4、作用域的注解
- 5、xml配置与注解对比
Spring 框架学习(七)---- bean自动装配、注解开发
一、Bean的自动装配
先说一下什么叫自动装配
自动装配就是给bean中的属性进行设置值进行注入,如果是引用类型的话,spring会在上下文中进行查找进行装配属性。
我们先搭建一个可以实现装配的环境
Fish类,拥有swim方法
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class Fish
public void swim()
System.out.println("小鱼会游泳!");
Bird类,拥有Fly方法
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
public class Bird
public void fly()
System.out.println("小鸟会飞!");
Peopel类,Fish和Bird都是人的宠物,所以这两个对象作为属性要装配到peopel类中
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter@ToString
public class Peopel
private Bird bird;
private Fish fish;
1、在xml中显式的配置
(1)ByName
首先将Fish类和Bird类注册到bean中,在peopel的bean中配置autoWird 类型根据名字进行自动装配
<bean id="fish" class="com.bit.pojo.Fish"/>
<bean id="bird" class="com.bit.pojo.Bird"/>
<bean id="peopel" class="com.bit.pojo.Peopel" autowire="byName"/>
这里的autowird 后面写 byName 就是根据set后面跟的名字在上下文中进行查找,然后进行装配。
那么如果byName 没有在上下文中查找这个名字呢?
<bean id="fish2222222" class="com.bit.pojo.Fish" primary="true"/>
<bean id="bird" class="com.bit.pojo.Bird"/>
<bean id="peopel" class="com.bit.pojo.Peopel" autowire="byName"/>
那么就会报错,Fish属性对象根据Name没有查找到,所以报空指针异常
如果我们bean的id与set后面的值不一致该怎么进行自动装配呢?
(2)ByType
<bean id="fish2222222" class="com.bit.pojo.Fish"/>
<bean id="bird2222222" class="com.bit.pojo.Bird"/>
<bean id="peopel" class="com.bit.pojo.Peopel" autowire="byType"/>
这里autoWird后面跟的 byType 是根据属性的类型进行查找,所以在上面的xml文件中 id全部与set后面跟的值不一致,我们看能否运行成功
public static void main(String[] args)
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Peopel peopel = context.getBean("peopel", Peopel.class);
peopel.getBird().fly();
peopel.getFish().swim();
查看运行结果
如果一个类型的bean有多个,能查找成功吗?
答案是会报错,不管是 byName 还是 byType 必须得找到唯一的bean才能装配成功。我们可以在同一类型的某个bean中加上primary:ture,那么可以运行成功
<bean id="fish1" class="com.bit.pojo.Fish" primary="true"/>
<bean id="fish2" class="com.bit.pojo.Fish"/>
<bean id="bird2222222" class="com.bit.pojo.Bird"/>
<bean id="peopel" class="com.bit.pojo.Peopel" autowire="byType"/>
总结
1.byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id
2.byType: 会自动在容器上下文中查找,和自己对象属性类型相同的bean
注意点
-
Byname的时候,需要保证所有bean的id唯一,并且这个bean的id需要和自动注入属性的set方法后面的字段一致
-
ByType的时候,需要保证所有bean的class唯一,并且这个bean的class需要和 注入属性的类型全限定名一致。
2、隐式的自动装配【重要】
使用注解进行开发
在使用注解之前,我们需要进行配置
-
加入contetx约束
-
加入注解支持
-
加入扫描(扫描包下的注解)
Spring 支持注解的代码
<?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
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1.在上面加上 context的xml约束-->
<!-- 2.加上注解支持-->
<context:annotation-config/>
<!-- 3.最好加上扫描注解的xml-->
<context:component-scan base-package="包名"/>
</beans>
(1)@Autowired
@Autowired 是默认根据ByType进行配置,如果有多个类型的bean,那么
直接在属性上用即可,也可以在set方法上面使用
使用Autowired我们可以不用编写set方法了,前提是你这个自动装配的属性在 Ioc 中已经存在了,且符合属性ByType唯一
注意点:
-
默认是 byType 的方式进行注入
-
如果有多个同一类型的bean,通过byName进行查找
-
如果按照名字进行查找
只是在xml文件中注册bean对象
<bean id="bird" class="com.bit.pojo.Bird"/>
<bean id="bird1" class="com.bit.pojo.Bird"/>
<bean id="fish" class="com.bit.pojo.Fish"/>
<bean id="fish1" class="com.bit.pojo.Fish"/>
<bean id="peopel" class="com.bit.pojo.Peopel"/>
Peopel类中对 两个属性标记Autowired注解
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
@Setter
@Getter
@ToString
public class Peopel
@Autowired
private Bird bird;
@Autowired
private Fish fish;
测试是否装配成功
public static void main(String[] args)
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Peopel peopel = context.getBean("peopel", Peopel.class);
peopel.getBird().fly();
peopel.getFish().swim();
运行成功。
Autowired注解默认是按照 byType 进行查找的,
如果在容器中存在多个同一类型的bean,那么继续按照 byName 的方式进行查找,进行装配,
如果都不符合那么发生异常报错。
如果都不符合的情况下,我们还想要进行装配,那么怎么操作呢?
答案就是搭配@Qualifier进行使用
@Qualifier
如果在配置文件中,有多个相同类型的bean,同时bean的id与set后面的字段不一致,如下图
<bean id="bird1" class="com.bit.pojo.Bird"/>
<bean id="bird2" class="com.bit.pojo.Bird"/>
<bean id="fish1" class="com.bit.pojo.Fish"/>
<bean id="fish2" class="com.bit.pojo.Fish"/>
<bean id="peopel" class="com.bit.pojo.Peopel"/>
可以使用 @Autowired @Qualifier 进行搭配使用查找到上下文当中唯一的id
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@Setter
@Getter
@ToString
public class Peopel
@Autowired
@Qualifier(value = "bird1")
private Bird bird;
@Autowired
@Qualifier(value = "fish1")
private Fish fish;
-
@Qualifier 必须和@Autowired进行搭配使用
-
按照@Qualifier 中的value进行设置,查找上下文中id为 value的 唯一的bean
@Value
字段属性标记了这个注解,可以在注解后面的括号中进行这只该属性的值。
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
@Setter
@Getter
@ToString
public class Peopel
@Value("张三")
private String name;
public static void main(String[] args)
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Peopel peopel = context.getBean("peopel", Peopel.class);
System.out.println(peopel.getName());
也可以成功的注入属性
@Value 的作用
@Value 就相当于在bean中的一个标签
<property name="属性名" value="设置的值"/>
@Nullable
字段属性标记了这个注解,说明这个字段可以为null。
不是设置成null,而是可以为null
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.Nullable;
@Setter
@Getter
@ToString
public class Peopel
@Value("张三")
private String name;
public void test(@Nullable String name)
System.out.println(name);
(2)@Resource
这个注解与@Autowired的作用类似,@Resource是Java自带的注解,不是spring提供的,默认按照 byName进行装配
如果bean的id都不符合的话,那么根据byType方式进行查找
public class Peopel
@Resource
private Bird bird;
@Resource
private Fish fish;
<bean id="bird" class="com.bit.pojo.Bird"/>
<bean id="fish" class="com.bit.pojo.Fish"/>
<bean id="peopel" class="com.bit.pojo.Peopel"/>
运行结果
如果在注解的后面什么都不加的话,默认按照set后面的字段名进行查找,如果在注解中加入name=“XXXX”,可以按照指定id进行查找。
bean 的id名与set字段不一致
<bean id="bird1111" class="com.bit.pojo.Bird"/>
<bean id="fish1111" class="com.bit.pojo.Fish"/>
<bean id="peopel" class="com.bit.pojo.Peopel"/>
在Resource加上name=“”,查找指定ID的bean
import javax.annotation.Resource;
@Setter
@Getter
@ToString
public class Peopel
@Resource(name = "bird1111")
private Bird bird;
@Resource(name = "fish1111")
private Fish fish;
同样也运行成功
注意点
@Resource首先按照byName方式进行查找bean
如果所有的bean id都不符合要求,那么按照byType 的方式进行查找,此时此类型只有一个bean才会装配成功
@Autowired 和 @Resource的区别
1、Autowired是spring提供的注解,Resource是Java自带的
2、都是用来进行自动装配的,都可以放到属性字段和set方法上
3、@Autowired默认通过ByType方式实现,如果有多个bean,按照ByName 方式查找
4、@Resource默认通过ByName方式实现,如果找不到名字,那么按照ByType方式查找
5、执行顺序不同,ByType和ByName的顺序不同。
3、Java中显式配置
使用Java进行配置,完全不需要使用xml配置文件
(1)实体类,使用@Component交由Spring进行托管
package com.bit.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Setter
@Getter
@ToString
public class User
@Value("张三")
private String name;
(2)创建一个类,在类上加上@Configuration 使得这个类变成一个配置类,完全等价于之前的xml配置文件。
package com.bit.config;
import com.bit.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.bit")
public class Myconfig
@Bean
public User getUser()
return new User();
@ComponentScan(“包名”) 对包下的类中的注解进行扫描,使其生效
@Bean加在方法上面
-
返回值相当于class,因为在上面有import导入了包名所以不需要全限定名
-
方法名相当于id
一个@Bean修饰的方法相当于下面这个xml语句
<bean id="getUser" class="com.pojo.User"/>
(3)测试是否能够bean注册装配成功
package com.bit.service;
import com.bit.config.Myconfig;
import com.bit.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class UserService
public static spring框架学习:Bean的装配方式 ——基于注解的装配自动装配