Spring--基于注解管理bean

基于注解管理bean

实验一:标记与扫描

  1. 注解
    和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记
    的位置,然后针对这个位置按照注解标记的功能来执行具体操作。
    本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

举例:元旦联欢会要布置教室,蓝色的地方贴上元旦快乐四个字,红色的地方贴上拉花,黄色的地方贴上气球。
在这里插入图片描述
班长做了所有标记,同学们来完成具体工作。墙上的标记相当于我们在代码中使用的注解,后面同学们做的工作,相当于框架的具体操作。

  1. 扫描
    Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后
    续操作。

  2. 新建Maven Module
    在这里插入图片描述

  3. 创建Spring配置文件

  4. 标识组件常用的注解
    @Component:将类标识为普通组件
    @Controller:将类标识为控制层组件
    @Service:将类标识为业务层组件
    @Repository:将类标识为持久层组件
    注意:这几个标识组件都只能标识在类上,如果是接口,要标在接口的实现类上

区别:
通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。
对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辦组件的作用。

注意:星然它们本质上一样,但是为了代码的可读性,为了程序结构严谨我们肯定不能随便胡乱标记。

  1. 创建组件
@Controller
public class UserController {
}
@Repository
public class UserDaoImpl implements UserDao {
}
@Service
public class UserServiceImpl implements UserService {
}
  1. 扫描组件
<?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">

    <!--    扫描组件-->
    <!--
        context:exclude-filter:排除扫描
        type:设置排除扫描的方式
        type="annotation|assignable"
        annotation:根据注解的类型进行排除,expression中需要设置排除的注解的全类名
        assignable:根据类的类型进行排除,expression中需要设置排除的类的全类名

        context:include-filter:包含扫描
        注意:需要在context:component-scan标签中设置use-default-filters = "false"
        use-default-filters = "true",默认,所设置的包下的所有类都扫描,此时可以使用排除扫描
        use-default-filters = "false",所设置的包下的所有类都不扫描,此时可以使用包含扫描
    -->
    <context:component-scan base-package="com.bijing.spring" use-default-filters="true">
        <!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <!--        <context:exclude-filter type="assignable" expression="org.springframework.stereotype.Controller"/>-->
        <!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->

    </context:component-scan>
</beans>
  1. 测试
    @Test
    public void testIOCByAnnotation() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
        UserController userController = ioc.getBean(UserController.class);
        System.out.println(userController);
        UserService userService = ioc.getBean(UserService.class);
        System.out.println(userService);
        UserDao userDao = ioc.getBean(UserDao.class);
        System.out.println(userDao);
    }
  1. 组件所对应的bean的id
    通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写
    可以在注解后面配置id
@Controller("controller")
public class UserController {
}

public class IOCByAnnotationTest {

    /**
     * @Component:将类标识为普通组件
     * @Controller:将类标识为控制层组件
     * @Service:将类标识为业务层组件
     * @Repository:将类标识为持久层组件 @
     * 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写
     */

    @Test
    public void testIOCByAnnotation() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
        UserController userController = ioc.getBean("controller", UserController.class);
        System.out.println(userController);
        UserService userService = ioc.getBean(UserService.class);
        System.out.println(userService);
        UserDao userDao = ioc.getBean(UserDao.class);
        System.out.println(userDao);
    }
}

关于Dao层、Service层和Controller层

  1. Dao层也叫数据持久层,是直接和数据库打交道的(写进数据库的数据相对是持久的)。Dao层的设计一般都是先设计接口,然后再设计该接口的实现类
  2. Service层也叫服务层,主要处理业务逻辑。Service层的设计也是先结构后实现
  3. Controller也叫业务层,主要处理业务流程。Controller层主要是与前台互交,把前台传进来的参数进行处理

实验二:基于注解的自动装配

  1. 场景模拟
    在这里插入图片描述

  2. @Autowired注解

这个注解的功能就是为我们注入一个定义好的 bean

@Controller()
public class UserController {
    @Autowired
//    @Qualifier("userServiceImpl")
    private UserService userService;

    public void saveUser() {
        userService.saveUser();
    }
}
@Repository()
public class UserDaoImpl implements UserDao {

    @Override()
    public void saveUser() {
        System.out.println("保存成功");
    }
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
   // @Qualifier("userDaoImpl")
    private UserDao userDao;


    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void saveUser() {
        userDao.saveUser();
    }
}
  1. @Autowired注解其他细节
  • @Autowired注解能够标识的位置
    • 标识在成员变量上,此时不需要设置成员变量的set方法
    • 标识在set方法上
    • 为当前成员变量赋值的有参构造器上
  • @Autowired注解的原理
    • 默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
    • 若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果, 即将要赋值的属性的属性名作为bean的id匹配某个bean的属性值
    • 若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致
    • 此时可以在要赋值的属性上添加一个@Qualifier注解,通过该注解的value属性值指定某个bean的id,用这个bean给属性赋值
  • @Qualifier注解
@Controller()
public class UserController {
    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userService;

    public void saveUser() {
        userService.saveUser();
    }
}
//使用@Service注解默认id为userServiceImpl,这里的id和基于xml方式bean中的id一个意思.
// @Service("userService")自定义id为userService,
// 此时在UserController中就需要利用@Qualifier注解指定自动装配UserService的id为userService
// @Qualifier("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    @Qualifier("userDaoImpl")
    private UserDao userDao;


    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void saveUser() {
        userDao.saveUser();
    }
}
    <context:component-scan base-package="com.bijing.spring">
        <!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <!--        <context:exclude-filter type="assignable" expression="org.springframework.stereotype.Controller"/>-->
        <!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->

    </context:component-scan>
    <!--经过上面的扫描后IOC中已经有了相应的bean了,此时再添加bean,@Autowired就会根据name装配-->
    <!--    没有@Qualifier注解时,本应该根据name找userService,找不到,
    但是userService上@Qualifier("userServiceImpl")指定了userServiceImpl,所以找到了-->
    <bean id="userServiceImpl" class="com.bijing.spring.service.impl.UserServiceImpl"></bean>
    <bean id="userDaoImpl" class="com.bijing.spring.dao.impl.UserDaoImpl"></bean>
  • 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException
    • 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
    • 可以将required设置为false,此时能装配就装配,无法装配则使用属性默认值
  1. @Autowired工作流程
package com.bijing.spring.test;

import com.bijing.spring.controller.UserController;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author 毕晶
 * @date 2022/11/12 20:45
 */
public class IOCByAnnotationTest {

    /**
     * @Component:将类标识为普通组件
     * @Controller:将类标识为控制层组件
     * @Service:将类标识为业务层组件
     * @Repository:将类标识为持久层组件 #
     * 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写
     * 可以通过标识组件的注解的value属性值设置bean的自定义id
     * @Autowired: 实现自动装配功能的注解 #
     * 1.@Autowired注解能够标识的位置
     * a>标识在成员变量上,此时不需要设置成员变量的set方法
     * b>标识在set方法上
     * c>为当前成员变量赋值的有参构造器上
     * 2.@Autowired注解的原理
     * a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
     * b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果
     * 即将要赋值的属性的属性名作为bean的id匹配某个bean的属性值
     * c>若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致
     * d>此时可以在要赋值的属性上添加一个@Qualifier注解,通过该注解的value属性值指定某个bean的id,用这个bean给属性赋值
     * ##
     * 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException
     * 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
     * 可以将required设置为false,此时能装配就装配,无法装配则使用属性默认值
     */

    @Test
    public void testIOCByAnnotation() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
        UserController userController = ioc.getBean(UserController.class);
        System.out.println(userController);
        userController.saveUser();
//        UserService userService = ioc.getBean(UserService.class);
//        System.out.println(userService);
//        UserDao userDao = ioc.getBean(UserDao.class);
//        System.out.println(userDao);

    }
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SpringBean 管理是指 Spring 框架通过 IoC(控制反转)容器来管理 Java 对象(Bean),并提供了一系列的功能来管理这些 Bean,包括依赖注入、生命周期管理、作用域管理等。通过 SpringBean 管理,我们可以将对象的创建、依赖关系的维护等工作交给 Spring 容器来完成,从而降低了代码的耦合度,提高了代码的可维护性和可扩展性。 ### 回答2: Spring 是目前很流行的 Java 开发框架,其中一个重要的特征就是它强大的 Bean 管理能力。Bean 是 Spring 框架中最基本的对象,可以被理解为一个 Spring 环境下的普通 Java 对象。SpringBean 管理主要是通过 IOC 和 DI 两种方式实现的。 IOC(Inversion of Control)控制反转是 Spring 中最核心的设计思想之一,它是一种基于组件的编程范式。它将控制权从应用程序代码中转移给框架,由框架根据配置文件等配置信息来创建并管理对象。开发者不再为对象的实例化和属性赋值等处理编写复杂代码,只需要配置好对象之间的依赖关系即可。 在 Spring 中,所有的 Bean 都由容器来创建和管理Bean 的生命周期也是由容器来负责的,Bean 被创建、被配置、被注入依赖、被提供给其他 Bean 使用,直到销毁的整个过程都是由容器掌控的。 DI(Dependency Injection)依赖注入是 Spring 框架中实现 IOC 的方法之一,它是指在创建 Bean 时,将其需要依赖的其他 Bean 通过特定的方式注入到该 Bean 中,从而实现 Bean 之间的解耦。DI 可以通过构造函数注入、Set 方法注入、接口注入等方式来实现。 在 Spring 中,Bean 可以通过 XML 配置文件、注解或者 Java 配置类等多种方式进行指定和创建。在指定一个 Bean 的时候,开发者可以指定多种属性,例如该 Bean 的 Class、ID、Scope、Lazy-init、Depends-on 等。其中 Scope 主要用于控制 Bean 的作用域,Spring 默认提供了 5 种作用域,分别是 Singleton(单例)、Prototype(原型)、Request(请求)、Session(会话)、Global-session(全局会话)。开发者可以根据需求灵活选择。 总之,SpringBean 管理能力非常强大,极大地减轻了开发者的工作量,提高了应用程序的可维护性和灵活性。在实际开发中,熟练掌握 SpringBean 管理原理及应用场景,有利于编写高质量、易于扩展、易于维护的 Java 应用程序。 ### 回答3: Spring是一种框架,用于开发Java应用程序。它支持依赖注入和bean管理Bean是Spring中的一个重要概念,它是指一个由Spring容器管理的对象,这些对象可以是POJO(普通的Java对象)或EJB(企业Java Bean)。 SpringBean管理机制通过IoC(控制反转)实现,即将创建对象的过程交由Spring容器管理,程序员只需要配置好相应的Bean定义即可。Bean被组织成一个Bean工厂,即ApplicationContext,这个工厂在应用程序启动的时候自动创建,并负责实例化和注入所有的Bean。 Spring中的Bean可以通过XML配置文件、Java注解和基于Java的配置类进行配置。最常见的方式是使用XML配置文件,通过配置文件中定义的Bean的ID,Spring容器可以自动从工厂中找到相应的Bean并注入到程序中。 在Spring中,Bean可以被分为多个不同的作用域,如singleton(单例)、prototype(原型)、request(请求)、session(会话)和global-session(全局会话)。其中,singleton作用域是默认的作用域,即一个Bean只会被创建一次,并在整个应用中共享使用。 总之,SpringBean管理机制让我们的开发变得更加灵活和高效,充分利用Spring的依赖注入和Bean管理,可以帮助开发者更好地管理对象,降低应用程序的耦合性,并提高代码的可维护性和可测试性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值