Spring学习笔记(三)

16 篇文章 0 订阅
9 篇文章 0 订阅

7、Bean的自动装配

自动装配是 Spring 满足 bean 依赖的一种方式!

Spring 会在上下文中自动寻找,并自动给bean 装配属性!

在Spring中有三种装配方式

  • 在 xml 中显示配置
  • 在 java 中显示配置
  • 隐式的自动装配bean

7.1、测试

1.环境搭建

  • 一个人 有两个宠物!

7.2、ByName 自动装配

会自动在容器上下文中查找,和自己对象 set 方法后面的值相对应的beanid。需要保证beanID是唯一的

<bean id="cat"  class="com.lsw.pojo.Cat"/>
    <bean id="dog"  class="com.lsw.pojo.Dog"/>
<bean id="person" class="com.lsw.pojo.Person" autowire="byName">
        <property name="name" value="时倾"/>
    </bean>

7.3、ByType自动装配

会自动在容器上下文中查找,和自己对象属性类型相同的bean!id 可以省略了~但是 必须唯一

   <bean  class="com.lsw.pojo.Cat"/>
    <bean  class="com.lsw.pojo.Dog"/>
    <bean id="person" class="com.lsw.pojo.Person" autowire="byType">
        <property name="name" value="时倾"/>
    </bean>

小结

  • ByName 的时候,需要保证所有的bean的 id 唯一,并且这个bean需要和自动注入属性的 set 方法的值保持一致。
  • ByType 的时候,需要保证所有的bean的 class 唯一,并且这个bean需要和自动注入属性的 类型保持一致。

7.4、注解实现自动装配

jdk 1.5 支持注解。Spring2.5就支持注解

The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.

要使用注解须知

  • 导入约束。context约束
  • 配置注解和支持<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
        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>
@Autowired

在属性上使用即可,也可以在 set 上使用

此时可以省略 set 方法,前提 是自动装配的属性在 IOC (Spring)容器中存在,且符合 ByType

✈️ 注意

在使用@Autowired时,首先在容器中查询对应类型的bean【ByType】

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

如果查询的结果不止一个,那么@Autowired会根据名称来查找。需要借助

@Qualifier标记,来指定需要装配bean的名称【ByName】

public class Person {
    @Autowired
    private Cat cat;
    @Autowired
    private  Dog dog;
    private String name;
    public Cat getCat() {
        return cat;
    }
    public Dog getDog() {
        return dog;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "cat=" + cat +
                ", dog=" + dog +
                ", name='" + name + '\'' +
                '}';
    }
}

如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false

@Nullable  //字段标记了这个注解,说明这个字段可以为 NULL
//如果显式的定义了 @autowired 的 required 为 false说明这个对象可以为空,否则不能为空
    @Autowired(required = false)
    private Cat cat;

借助@Qualifier标记,来指定需要装配bean的名称@Qualifier(value = "xxx")

@Autowired
@Qualifier(value = "cat22")
private Cat cat;
@Autowired
@Qualifier(value = "dog22")
private  Dog dog;
 		<bean id="cat22"  class="com.lsw.pojo.Cat"/>
    <bean id="dog22" class="com.lsw.pojo.Dog"/>

    <bean id="cat11"  class="com.lsw.pojo.Cat"/>
    <bean id="dog11" class="com.lsw.pojo.Dog"/>

    <bean id="person" class="com.lsw.pojo.Person"/>
    <context:annotation-config/>

也就是说:如果@Autowired 自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配合 @Autowired 的使用,指定一个唯一的bean 对象注入。

@Nullable

字段标记了这个注解,说明这个字段可以为 Null

@Resource

@Resource是 java 原生自带的注解 ,其功能和 @Autowired大致相同

当存在多个相同类型的对象时,也是可以通过指定 name 来进行指定特定类

效率相对于 @Autowired比较低

    @Resource(name = "cat")
    private Cat cat;
    @Resource
    private  Dog dog;
    <bean id="cat"  class="com.lsw.pojo.Cat"/>
    <bean id="cat22"  class="com.lsw.pojo.Cat"/>
    <bean id="dog22" class="com.lsw.pojo.Dog"/>

小结

@Autowired@Resource的区别:

  • @Autowired@Resource都可以用来装配bean. 都可以写在属性字段上,或写在setter方法上。
  • @Autowired默认按照 ByType 来实现的,如果查找到多个,则按照 ByName 来查找。
  • @Resource默认按照 ByName 来实现的,如果查找到多个,则按照 ByType 来查找。
  • @Autowired按照名字进行查找的时候 需要借助@Qualifier(value = "xxx")来标记

@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;

@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

@Resource(name="baseDao")
private BaseDao baseDao;

推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

*个人认为 @Resource 很难有个明确的默认,要是没有指定 name 就是安装 默认名字,没有找到则按照类型来,可不可以 认为 他就是默认按照类型的,要是需要按照名字来 需要进行指定。*纯属个人理解,如果说的不对,可以下方留言交流。

8、使用注解开发

在 Spring4 之后,要使用注解开发,要保证 AOP 的包导入了

在这里插入图片描述

在使用注解需要 导入 context 约束,增加注解的支持

<?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:component-scan base-package="com.lsw"/>
    <context:annotation-config/>

</beans>
1、bean
+ @Component : 组件,放在类上,说明这个类被Spring 管理了,就是bean 等价于 <bean id="user" class="com.lsw.pojo.User"/>
2、属性如何注入
 + @Value("李白") : 相当于<property name="name" value="李白"/>

//@Component 组件
//等价于<bean id="user" class="com.lsw.pojo.User"/>
@Component
public class User {
//@Value("李白")
//相当于<property name="name" value="李白"/>
    public String name ;
    @Value("李白")
    public void setName(String name) {
        this.name = name;
    }
}

3、衍生的注解

@Component有几个衍生注解,我们在web开发中,会按照 MVC 三层架构分层!

  • dao层【@Repository
  • service层【@Service
  • controller层【@Controller

这四个注解的功能都是一样的,都是代表将某个类注册到 Spring 中,装配 Bean

4、自动装配置
  • @Autowired
  • @Resource
5、作用域
  • @Scope("singleton")——> 单例模式
  • @Scope("prototype")——>原型模式
6、小结

xml 与 注解

  • xml 更加万能,适用于任何场合,维护简单方便
  • 注解 不是自己的类无法使用,不能进行引用,维护相对复杂

最佳实践:

  • xml 用来管理 bean
  • 注解只完成属性的注入
  • 我们在使用的过程中只需要注意一个问题,必须让注解生效,就需要开启注解支持。
<!--    指定要扫描的包,这个包下的注解就会生效!-->
    <context:component-scan base-package="com.lsw"/>
    <context:annotation-config/>

9、使用java的方式配置Spring

@Configuration

【涉及到底层的关系】

我们现在要完全不使用Spring的xml配置了,全权交给 Java 来做

JavaConfig 是 Spring的一个子项目,在Spring4 之后,他成为了一个核心功能。

实体类

//@Component
//这个注解的意思,就是说明这个类被Spring接管了,注册到容器中
public class User {
    private String name;
    public String getName() {
        return name;
    }
    @Value("时倾aaa")
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

配置类

@Configuration
//这个也会被Spring 托管,注册到容器中,因为他本来就是一个@Component,@Configuration代表这是一个配置类,就和之前的beans.xml一样
@ComponentScan("com.lsw.pojo")
@Import(SqConfig2.class)
public class SqConfig {
    @Bean
//    注册了一个bean,就相当于我们之前写的一个bean 标签。
//    这个方法的名字就相当于bean 标签中的id属性
//    这个方法的返回值就相当于bean标签中的class属性
    public User getUser(){
        return new User();//就是返回要注入到bean的对象!
    }
}

测试类

public class MyTest {
    public static void main(String[] args) {
//        如果我们完全使用了配置类的方式去做,我们就只能通过AnnotationConfig 上下文来获取容器。通过配置类的class对象加载
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SqConfig.class);
        User getUser = context.getBean("getUser", User.class);
        System.out.println(getUser.getName());
    }
}

这种的纯 Java 配置方式,在Springboot中随处可见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值