【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

这篇具有很好参考价值的文章主要介绍了【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解),Spring进阶系列,spring,java,后端,spring boot

一、说明

回顾一下基于xml配置的Spring对Bean的管理 ,对Bean的完整管理如下所示:

<bean id="" class="" init-method="" destroy-method="" scope="">
    <property name="" value=""/>
    <property name="" ref=""/>
</bean>

分析可以发现:我们对Bean的管理就四个方面,分别是:

  • 用于创建对象的
  • 用于注入数据的
  • 用于改变Bean的作用域的
  • 和Bean的生命周期相关的

其实对于注解来说,也是包括了这四个方面,换句话说,使用注解的方式管理Bean和使用xml的方式管理Bean作用是完全一样的,区别仅仅在于配置的形式不同而已。

二、用于创建对象的

2.1、Component注解

2.1.1、定义Bean

@Component
public class DogService {
    
}

2.1.2、主配置文件配置扫描注解

<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">

    <!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>

</beans>

2.1.3、测试

 @Test
public void testDogServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        DogServiceImpl dogService = (DogServiceImpl) ac.getBean("dogServiceImpl");

        System.out.println(dogService);
}

2.1.4、Component注解总结

  • 作用

    ​ 用于把对当前修饰的类创建出来,并存放到Spring容器中。

  • 属性

    ​ a. 用该注解所创建的对象默认的id名称是当前类名,且首字母改小写

    ​ b. 可以通过value属性手动的指定bean的id。

2.2、Controller注解

​ 一般用在表现层,例如SpringMVC、Struts2

2.3、Service注解

​ 一般用在业务层,例如Service层

2.4、Repository注解

​ 一般用在持久层7.2.5、总结

  • Controller、Service、Repository这三个注解他们的作用和属性与Component是一模一样。
  • 既然一模一样,之所以Spring框架还要提供,主要是Spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
  • 他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的

三、用于注入数据的

3.1、Autowired注解

作用:

​ 自动按照类型注入。

3.1.1、定义Bean

// 用户service接口
public interface UserService {
	public void printUserDao();
}
// 用户service接口实现,bean的名称改为:userService
@Service("userService")
public class UserServiceImpl implements UserService {
	
  	@Autowired
    private UserDao userDao;

    // 打印UserDao,看是否可以将值打印出来,如果打印出来说明值真的注入成功了
    public void printUserDao(){
        System.out.println(userDao);
    }
}
// 用户UserDao接口
public interface UserDao {

}
// 用户UserDao接口实现,bean的名称改为:userDao01
@Repository("userDao01")
public class UserDaoImpl01 implements UserDao {

}

3.1.2、主配置文件配置扫描注解

<beans>
	<!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>
</beans>

3.1.3、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        UserService userService = (UserService) ac.getBean("userService");

        userService.printUserDao();	// cn.bdqn.dao.impl.UserDaoImpl@7a52f2a2
}

3.1.4、改造

假设系统中存在两个UserDao的实现,现在再添加一个。现在再添加测试:

@Repository("userDao02")
public class UserDaoImpl02 implements UserDao {

}

再次运行程序,会发现,程序报错:

No qualifying bean of type 'cn.bdqn.dao.UserDao' available: expected single matching bean but found 2: userDao01,userDao02

翻译:没有找到一个可用的UserDao,期望能够匹配一个,但是发现了2个。换句话说,由于是根据类型匹配的,而userDao01,userDao02都是符合注入的类型的,不知道要用哪个了.

该如何解决呢?既然Spring不知道具体要用哪个了,那我们由开发者来去指定其中的一个告诉Spring你就用这个注入就可以了,那么实现方式就是:通过名称告诉即可

解决方案:

@Service("userService")
public class UserServiceImpl implements UserService {

  	// 将变量的名称修改为userDao01,那么依赖注入的时候就使用UserDaoImpl01
    @Autowired
    private UserDao userDao01;
}

再次测试,程序正常执行。

3.1.5、总结

  • 该注解是根据类型自动注入,假如只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
  • 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
  • 如果容器中有多个bean对象类型和要注入的变量类型匹配,则可能会发生错误,解决办法就是修改变量的名称为其中的某一个bean的名称

3.2、Qualifier注解

​ 在7.3.1章节使用Autowired注解的时候,会存在一个问题,就是如果系统中存在多个类型的Bean都匹配的时候,就会找不到到底要使用哪个Bean对象了,会报错,我们采取的解决办法是:修改变量名即可解决 , 但是这种做法实际上是挺菜的,我现在就想使用userDao这个变量名,那么能否有一种更好的解决办法呢?答案是肯定的,即使用Qualifier注解。

3.2.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean,修改如下:

public class UserServiceImpl implements UserService {

    @Autowired
    @Qualifier(value = "userDao01")	// 通过此注解中的value属性明确指定要用哪个name的bean
    private UserDao userDao;
}

3.2.2、总结

  • 在按照类型注入的基础之上再按照名称注入,它在给类的成员变量注入时不能单独使用,需要搭配Autowired注解。

3.3、Resource注解

3.3.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean,修改如下:

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource(name = "userDao01")
    private UserDao userDao;
}

3.3.2、总结

  • 该注解采用的是直接按照bean的id注入,它可以独立使用,name用于指定bean的id。

注意:

使用Autowired、Qualifier以及Resource这三个注解都只能注入其他bean类型的数据,对于基本数据类型和String类型是无法通过使用该3个注解实现。同时,对于集合数据类型的注入只能通过XML来实现。


3.4、Value注解

作用:

​ 用于注入基本类型和String类型的数据。

3.4.1、案例1

3.4.1.1、定义Bean
@Component("jdbcUtils")
public class JdbcUtils {

    @Value("com.mysql.jdbc.Driver")
    private String driverClass;
}
3.4.1.2、测试
@Test
public void testJdbcUtils() throws Exception{
    // 1、读取主配置文件信息,获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    JdbcUtils utils = (JdbcUtils) ac.getBean("jdbcUtils");

    System.out.println(utils);	// com.mysql.jdbc.Driver
}

3.4.2、案例2

如果Value注解用于案例1,那这样太菜了,我们要为driverClass这个变量赋值,那岂不是直接赋值得了,还需要搞一个Value直接赋值吗?显然是没有必要的,所以一般来说,Value注解常用于对配置文件内容的读取。

3.4.2.1、创建db.properties文件
driverClass=com.mysql.jdbc.Driver
port=3306
3.4.2.2、主配置文件需要将properties文件引入进来
<beans>
	
  	<!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>
    
  	<!-- 将properties文件引入到Spring框架中-->
    <context:property-placeholder location="classpath:db.properties"/>
</beans>
3.4.2.3、定义Bean
@Component("jdbcUtils")
public class JdbcUtils {

    @Value("${driverClass}")
    private String driverClass;

    @Value("${port}")
    private Integer port;
}
3.4.2.4、测试
@Test
public void testJdbcUtils() throws Exception{
    // 1、读取主配置文件信息,获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    JdbcUtils utils = (JdbcUtils) ac.getBean("jdbcUtils");

    System.out.println(utils);	// com.mysql.jdbc.Driver,3306
}

3.4.3、总结

该注解通过可以实现对基本数据类型和String类型的注入,并且是支持使用Spring的EL表达式。那么对于Spring的EL表达式的语法就是:${表达式}。

3.5、大总结

以上注解的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的

四、用于改变Bean的作用域的

方式:

  • 使用Scope注解,作用是用于指定bean的作用范围。该注解有一个value属性,可以指定范围的取值,常用取值:singleton、 prototype
  • 该Scope注解默认的value值就是单例的【singleton】

4.1、定义Bean

Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean修改作用域,修改如下:

@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService{
  
}

4.2、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        UserService userService = (UserService) ac.getBean("userService");
        UserService userService2 = (UserService) ac.getBean("userService");

        System.out.println(userService == userService2); // true
}

改造一下:如果将上例的UserServiceImpl中的Scope改为prototype,则再次测试的时候会返回false。

4.3、总结

Scope该注解的作用就和在bean标签中使用scope属性实现的功能是一样的

五、和Bean的生命周期相关的

5.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean添加了一个初始化方法和销毁方法。

@Service("userService")
public class UserServiceImpl implements UserService {

    @PostConstruct
    public void init(){
        System.out.println("对象初始化了");
    }
    
    @PreDestroy
    public void destroy(){
        System.out.println("对象销毁了");
    }
}

5.2、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        ac.close();
}

// 对象初始化了
// 对象销毁了

5.3、总结

这个两个注解作用就和在bean标签中使用init-method和destroy-methode的作用是一样的。


【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解),Spring进阶系列,spring,java,后端,spring boot文章来源地址https://www.toymoban.com/news/detail-777572.html

到了这里,关于【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring进阶系列丨第五篇】详解Spring中的依赖注入

    全称 Dependency Injection(DI) 与IoC的关系 IoC和DI其实说的是一个意思,可以这么说: IoC是一种思想,DI是对这种思想的一种具体实现 依赖关系的管理 以后都交给spring来维护,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明。 依赖关系的维护

    2024年02月04日
    浏览(58)
  • 【Spring进阶系列丨第七篇】Spring框架新注解分类及详解

    1.1.1、定义一个类 1.1.2、使用Configuration注解修饰类 1.1.3、作用 ​ 使用Configuration注解修饰的类表示的是:当前类是一个配置类。该类的作用和beans.xml是一样的,换句话说,该 注解所修饰的类就是用来代替beans.xml文件的。 1.2.1、定义bean 1.2.2、在主配置类中注册bean ​ 在以前,

    2024年04月10日
    浏览(94)
  • 【Spring进阶系列丨第八篇】Spring整合junit & 面向切面编程(AOP)详解

    ​ @ContextConfiguration注解需要注意的细节是: classes:指定的是主配置类的字节码 locations:指定xml文件的位置 ​ 首先来看一个问题,假如我现在有一个UserServiceImpl用户业务类,其中呢,有一个保存用户的方法,即: ​ 现在的需求是:我要在保存用户之前新增事务的功能,你

    2024年04月13日
    浏览(58)
  • 【Spring进阶系列丨第三篇】Spring核心技术之 IoC 与 DI 实战案例

    在上一篇文章中,我们学习了IoC与DI的相关概念与原理,现在让我们 以HelloWorld为例,编写一个程序,让创建对象的工作由Spring帮助我们创建。 一同感受一下Spring框架带给我们开发的便捷性。 这种做法是以前最常用的做法,HelloWorld这个类的对象是我们程序员自己去创建并为属

    2024年02月05日
    浏览(51)
  • 【Spring进阶系列丨第二篇】Spring中的两大核心技术IoC(控制反转)与DI(依赖注入)

    我们都知道Spring 框架主要的优势是在 简化开发 和 框架整合 上,至于如何实现就是我们要学习Spring 框架的主要内容,今天我们就来一起学习Spring中的两大核心技术IoC(控制反转)与DI(依赖注入)。 以经典的三层架构MVC作为案例,以前我们都是这么干的,看如下代码: 按照

    2024年02月05日
    浏览(70)
  • 微服务开发系列 第六篇:Redisson

    A、技术栈 开发语言:Java 1.8 数据库:MySQL、Redis、MongoDB、Elasticsearch 微服务框架:Spring Cloud Alibaba 微服务网关:Spring Cloud Gateway 服务注册和配置中心:Nacos 分布式事务:Seata 链路追踪框架:Sleuth 服务降级与熔断:Sentinel ORM框架:MyBatis-Plus 分布式任务调度平台:XXL-JOB 消息中间

    2024年02月07日
    浏览(55)
  • spring boot学习第六篇:SpringBoot 集成WebSocket详解

    1、WebSocket简介 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 2、为什么需要WebSocket HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接。 无状态:每次连

    2024年01月21日
    浏览(51)
  • 第六篇 弹性云计算中的资源管理技术

    作者:禅与计算机程序设计艺术 云计算已经成为当下热门话题之一,随着互联网、移动互联网和物联网等新一代技术的发展,云计算正在向更加复杂、弹性、便利的方向发展。但是在云计算平台上运行的应用越来越多,服务种类也越来越丰富,同时作为一个庞大的系统,其使

    2024年02月07日
    浏览(52)
  • Spring系列三:基于注解配置bean

    上文中, 我们学习到了 Spring系列二:基于XML配置bean 接下来我们学习, 通过注解配置bean 基于注解的方式配置 bean , 主要是项目开发中的组件, 比如 Controller, Service 和 Dao. 组件注解的形式有 1. @Component 表示当前注解标识的是一个组件 2. @Controller 表示当前注解标识的是一个控制器

    2024年02月13日
    浏览(40)
  • Spring系列二:基于XML配置bean

    上文中, 我们学习到了 Spring系列一:spring的安装与使用 接下来我们学习, 通过XML配置bean Bean管理包括两方面: 创建bean对象, 给bean注入属性 案例: 通过spring的ioc容器, 获取一个bean对象, 获取方式: 按类型. 演示通过bean的类型获取对象 细节 按照类型获取bean, 要求ioc容器中的同一个

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包