一文打通基于注解管理Bean(一)

简介: 一文打通基于注解管理Bean

f8854864de5e426982d91ed0904b08bc.png

从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

Spring 通过注解实现自动装配的步骤如下:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

开启组件扫描

Spring 默认不使用注解装配 Bean,因此我们需要在 Spring 的 XML 配置中,通过 context:component-scan 元素开启 Spring Beans的自动扫描功能。开启此功能后,Spring 会自动从扫描指定的包(base-package 属性设置)及其子包下的所有类,如果类上使用了 @Component 注解,就将该类装配到容器中。

1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:context="http://www.springframework.org/schema/context"
5. xsi:schemaLocation="http://www.springframework.org/schema/beans
6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7.     http://www.springframework.org/schema/context
8.             http://www.springframework.org/schema/context/spring-context.xsd">
9. <!--开启组件扫描功能-->
10. <context:component-scan base-package="com.atguigu.spring6"></context:component-scan>
11. </beans>

注意:在使用 context:component-scan 元素开启自动扫描功能前,首先需要在 XML 配置的一级标签 <beans> 中添加 context 相关的约束。

情况一:最基本的扫描方式  

1. <context:component-scan base-package="com.atguigu.spring6">
2. </context:component-scan>

情况二:指定要排除的组件

1. <context:component-scan base-package="com.atguigu.spring6">
2. <!-- context:exclude-filter标签:指定排除规则 -->
3. <!-- 
4.      type:设置排除或包含的依据
5.    type="annotation",根据注解排除,expression中设置要排除的注解的全类名
6.    type="assignable",根据类型排除,expression中设置要排除的类型的全类名
7.  -->
8. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
9. <!--<context:exclude-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
10. </context:component-scan>

情况三:仅扫描指定组件

1. <context:component-scan base-package="com.atguigu" use-default-filters="false">
2. <!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
3. <!-- use-default-filters属性:取值false表示关闭默认扫描规则 -->
4. <!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 -->
5. <!-- 
6.      type:设置排除或包含的依据
7.    type="annotation",根据注解排除,expression中设置要排除的注解的全类名
8.    type="assignable",根据类型排除,expression中设置要排除的类型的全类名
9.  -->
10. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
11.   <!--<context:include-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
12. </context:component-scan>

使用注解定义 Bean

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。

注解 说明
@Component 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Autowired注入

单独使用@Autowired注解,默认根据类型装配。【默认是byType】

源码:

1. @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
2. @Retention(RetentionPolicy.RUNTIME)
3. @Documented
4. public @interface Autowired {
5. boolean required() default true;
6. }

源码中有两处需要注意:

  • 第一处:该注解可以标注在哪里?
  1. 构造方法上
  2. 注解上
  3. 属性上
  4. 形参上
  5. 方法上
  • 第二处:该注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在的话就注入,不存在的话,也不报错。

①场景一:属性注入

创建UserDao接口

1. public interface UserDao {
2. 
3. public void print();
4. }

创建UserDaoImpl实现

1. @Repository
2. public class UserDaoImpl implements UserDao {
3. 
4. @Override
5. public void print() {
6.         System.out.println("Dao层执行结束");
7.     }
8. }

创建UserService接口

1. public interface UserService {
2. 
3. public void out();
4. }

创建UserServiceImpl实现类

1. @Service
2. public class UserServiceImpl implements UserService {
3. 
4. @Autowired
5. private UserDao userDao;
6. 
7. @Override
8. public void out() {
9.         userDao.print();
10.         System.out.println("Service层执行结束");
11.     }
12. }

创建UserController类

1. @Controller
2. public class UserController {
3. 
4. @Autowired
5. private UserService userService;
6. 
7. public void out() {
8.         userService.out();
9.         System.out.println("Controller层执行结束。");
10.     }
11. 
12. }

测试

1. public class UserTest {
2. 
3. private Logger logger = LoggerFactory.getLogger(UserTest.class);
4. 
5. @Test
6. public void testAnnotation(){
7. ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
8. UserController userController = context.getBean("userController", UserController.class);
9.         userController.out();
10.         logger.info("执行成功");
11.     }
12. 
13. }

以上构造方法和setter方法都没有提供,经过测试,仍然可以注入成功。

②场景二:set注入

修改UserServiceImpl类

1. @Service
2. public class UserServiceImpl implements UserService {
3. 
4. private UserDao userDao;
5. @Autowired
6. public void setUserDao(UserDao userDao) {
7. this.userDao = userDao;
8.     }
9. 
10. @Override
11. public void out() {
12.         userDao.print();
13.         System.out.println("Service层执行结束");
14.     }
15. }

修改UserController类

1. @Controller
2. public class UserController {
3. 
4. private UserService userService;
5. 
6. @Autowired
7. public void setUserService(UserService userService) {
8. this.userService = userService;
9.     }
10. 
11. public void out() {
12.         userService.out();
13.         System.out.println("Controller层执行结束。");
14.     }
15. 
16. }

测试:成功调用


相关文章
|
XML Java 数据格式
基于注解管理bean~
基于注解管理bean~
|
XML Java 数据库连接
“Spring管理JavaBean的过程及Bean的生命周期“
“Spring管理JavaBean的过程及Bean的生命周期“
118 0
|
6月前
|
XML Java 数据格式
Spring注解开发管理第三方bean及依赖注入
Spring注解开发管理第三方bean及依赖注入
112 0
|
5月前
|
缓存 Java Spring
Bean 的创建和管理
Bean 的创建和管理
39 3
|
5月前
|
XML Java 数据格式
Spring框架第三章(基于注解管理bean)
Spring框架第三章(基于注解管理bean)
|
6月前
|
Java Spring
Spring注解开发bean管理及依赖注入
Spring注解开发bean管理及依赖注入
63 0
|
6月前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
96 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
缓存 Java 开发者
Spring Bean的生命周期全过程
大家好,我是被编程耽误的文艺Tom。今天能给大家介绍一下Spring Bean生命周期全过程,这道题呢也是大厂高频面试题。接下来我给大家做一个详细的分析和解答。
108 0
|
Java Spring
一文打通基于注解管理Bean(二)
一文打通基于注解管理Bean(二)
|
XML 存储 缓存
一文搞定 Spring Bean 的创建全过程!
Spring模块概览,绿色是模块,Spring中八大模块,黑色表示该模块包含的jar包(组件)。例如我们想要用IOC容器,也就是绿色的Cor
一文搞定 Spring Bean 的创建全过程!