Spring 全家桶之 Spring Framework 5.3(四)(上)

简介: Spring 全家桶之 Spring Framework 5.3(四)

一、@Controller,@Service,@Repository,@Component注解

创建一个新的工程spring-bean-anno,并导入依赖

<properties>
    <spring-version>5.3.13</spring-version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.14</version>
    </dependency>
</dependencies>
复制代码

新建四个包controller,service,dao,entity,分别增加四个类UserController,UserService,UserDao,User

public class UserController {
}
复制代码
public class UserService {
}
复制代码
public class UserDao {
}
复制代码
public class User {
    private String username;
    private String password;
    private String email;
    private String signature;
    // 此处省略getter/setter/toString方法
}
复制代码

在前三个类上加上注解@Controller,@Service,@Repository

  • @Controller:给controller包中的xxxController加上这个注解
  • @Service:给service包中的XxxService实现类添加这个注解
  • @Repository:给持久层增加这个注解
  • @Component:给任何注册到Spring容器中的组件或类添加这个注解

具体操作为:先在类上加相应注解,再增加xml配置自动扫描范围

resources目录下新建一个annotation.xml配置文件配置扫描范围

<?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:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p" 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/util
        http://www.springframework.org/schema/util/spring-util-4.3.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.citi">
    </context:component-scan>
</beans>
复制代码

增加测试类

public class AnnotationTest {
    @Test
    public void testGetBeanByAnnotation(){
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:annotation.xml");
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }
}
复制代码

执行测试方法,默认Bean的ID为类名首字母小写

image.png

自定义bean的id只需要在注解后添加bean的id即可,如@Controller("controller"),再次执行测试

image.png

使用注解和xml配置默认都是单例模式,注解模式使用多例需要在类上添加@Scope注解,在UserController类上增加@Scope(value = "prototype"),增加测试方法

@Test
public void testGetBeanByAnnotationWithPrototype(){
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:annotation.xml");
    UserController userController = context.getBean(UserController.class);
    UserController userController1 = context.getBean(UserController.class);
    System.out.println(userController == userController1);
}
复制代码

执行测试,控制台打印出false

image.png

对于自定义的类要加入到容器中可以使用注解的方式,而对于一些工具类源码如数据库连接池就没有办法加注解,只能通过bean xml配置的方式注册到容器中去,通过注解+xml配置结合可以将任意组件加入到容器中去

二、component-scan,exclude-filter,include-filter标签

<context:component-scan> 标签默认全部配置的包中的全部加了注解的组件,如果想要排除某些组件需要在标签内使用exclude-filter标签,exclude-filter有type和expression两个属性

  • type=“annotation”:指定按照注解进行排除,expression则为注解的全类名
  • type=“assignable":指定排除具体的类,expression则为具体类的全类名
  • type="aspectj":aspectj表达式,expression则为具体表达式内容
  • type="customer":自定义实现TypeFilter接口
  • type="regex":正则表达式排除

annotation方式排除

xml中component-scan标签下增加配置,排除@Controller注解标注的Bean

<context:component-scan base-package="com.citi">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
复制代码

执行testGetBeanByAnnotation测试方法,控制台输出不包含userController

image.png

assignable方式排除

注销原来的配置,增加xml配置,排出userService

<context:component-scan base-package="com.citi">
    <context:exclude-filter type="assignable" expression="com.citi.service.UserService"/>
</context:component-scan>
复制代码

同样执行testGetBeanByAnnotation测试方法,控制台输出不包含userService

image.png

指定只扫描哪些可以使用include-filter标签,位置同样放在component-scan标签内,属性及Value都与exclude-filter一致,使用include-filter首先要禁用默认全部扫描

注销xml中原来的配置,新增只扫描UserService组件的配置

<context:component-scan base-package="com.citi" use-default-filters="false">
    <context:include-filter type="assignable" expression="com.citi.service.UserService"/>
</context:component-scan>
复制代码

执行testGetBeanByAnnotation测试方法,控制台输出只包含userService

image.png

三、依赖注入@Autowire注解

在UserDao中增加方法

public void insert(User user){
    System.out.println(this.getClass().getName() + "的insert方法被调用");
}
复制代码

@Autowire是按照类型注入,如果找不到会报错,如果找到多个相同类型的Bean会怎么样?存在多个同类型的Bean按照属性名为id继续装配 新增一个UserDaoExt类,继承UserDao,并加入容器中

@Repository
public class UserDaoExt extends UserDao {
    @Override
    public void insert(User user) {
        System.out.println(this.getClass().getName() + "的insert方法被调用");
        super.insert(user);
    }
}
复制代码

新增测试类

public class AutowireAnnotationTest {
    @Test
    public void testGetBeanByAnnotation(){
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:annotation.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.save(new User());
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
    }
}
复制代码

userService调用的是userDao的insert方法,说明是按照属性名来装配的

image.png

将UserService中属性名改为useDaoExt,再次执行测试,输出UserDaoExt的insert方法被调用,可以说明当存在多个相同类型的Bean时,@Autowire注解会根据属性名作为Bean的ID进行自动装配

image.png

@Qualifier()指定装配的Bean的ID

UserService中属性增加@Qualifier()注解

@Service
public class UserService {
    @Qualifier("userDao")
    @Autowired
    private UserDao userDaoExt;
    public void save(User user){
        System.out.println(this.getClass().getName() + "的save方法被调用");
        userDaoExt.insert(user);
    }
}
复制代码

再次执行测试,@Qualifier注解指定的userDao被调用

image.png


相关文章
|
7月前
|
Java 开发者 Spring
Spring Framework 中的 @Autowired 注解:概念与使用方法
【4月更文挑战第20天】在Spring Framework中,@Autowired 注解是实现依赖注入(Dependency Injection, DI)的一种非常强大的工具。通过使用 @Autowired,开发者可以减少代码中的引用绑定,提高模块间的解耦能力
731 6
|
4月前
|
安全 Java 网络安全
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
|
6月前
|
前端开发 Java 调度
Spring Webflux 是 Spring Framework 提供的响应式编程支持
Spring Webflux 是 Spring Framework 提供的响应式编程支持
88 2
|
5月前
|
Cloud Native Java 开发者
深入解析Spring Framework的核心设计原理
深入解析Spring Framework的核心设计原理
|
5月前
|
安全 Java Apache
如何安装与使用Spring Boot 2.2.x、Spring Framework 5.2.x与Apache Shiro 1.7进行高效开发
【7月更文第1天】在现代Java Web开发领域,Spring Boot以其简化配置、快速开发的特点备受青睐。结合Spring Framework的成熟与Apache Shiro的强大权限控制能力,我们可以轻松构建安全且高效的Web应用。本篇文章将指导你如何安装并使用Spring Boot 2.2.x、Spring Framework 5.2.x以及Apache Shiro 1.7来构建一个具备基础权限管理功能的项目。
92 0
|
7月前
|
设计模式 Java 数据库连接
Spring Framework 6 中的设计模式
Spring Framework 6 中的设计模式
50 1
|
7月前
|
前端开发 Java Spring
Spring Framework五大功能模块
Spring Framework五大功能模块
|
开发框架 安全 Java
Spring Framework远程代码执行漏洞复现(CVE-2022-22965)
Spring Framework存在远程代码执行漏洞,攻击者可通过该漏洞执行系统命令。
466 1
Spring Framework远程代码执行漏洞复现(CVE-2022-22965)
|
前端开发 Java 数据库连接
【面试题精讲】Spring Framework有哪些模块?
【面试题精讲】Spring Framework有哪些模块?
|
安全 Java 测试技术
Spring Framework中的Bean生命周期2
Spring Framework中的Bean生命周期2
83 0