Spring framework Day10:JSR330注入注解-CSDN博客
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
前言
JSR330是Java社区标准化进程Java Community Process简称JCP中的一个规范全名为"Dependency Injection for Java"即Java的依赖注入规范。它定义了一组注解和相关的规范用于实现依赖注入Dependency Injection简称DI。
依赖注入是一种设计模式旨在解耦应用程序中的不同模块或组件之间的依赖关系。通过依赖注入可以将对象的创建、维护和配置等责任从使用对象的代码中剥离出来并由容器负责提供和注入所需的依赖项。
一、开始学习
本次主学习三个注解@RequiredArgsConstructor、@Inject、@Named。那么它们分别是什么意思有什么用呢
@RequiredArgsConstructor
、@Inject
和@Named
是JSR330规范中的注解用于实现依赖注入。
@RequiredArgsConstructor
这是一个Lombok注解而不是JSR330规范中的注解。它可以用于生成一个包含所有标记为final
或@NonNull
的字段的构造函数。这样在使用@RequiredArgsConstructor
注解的类中就无需手动编写构造函数Lombok会自动帮我们生成。这在依赖注入中特别有用可以省去手动编写大量的构造函数代码。
@Inject
这是JSR330规范中的注解用于标记需要进行依赖注入的构造方法、字段或者方法。通过在目标类中标记@Inject
依赖注入框架会在需要的时候自动实例化并注入相应的依赖项。
@Named
也是JSR330规范中的注解用于为依赖项指定名称或者限定符。当一个接口有多个实现类时可以通过@Named
注解配合不同的名称来区分注入的具体实例。在使用@Inject
进行注入时可以结合@Named
注解指定要注入的具体实现。
这些注解都是为了简化依赖注入的使用并保持与JSR330规范的一致性。通过标记相关的注解我们可以更方便地使用依赖注入框架来管理和注入各个组件的依赖关系。
1、新建项目结构如下
2、导入 spring 依赖
<!-- spring 的核心依赖 -->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.5</version>
</dependency>
<!-- JSR 330 标准注入注解 -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
注意@Inject 不存在 JDK 11 中如果要使用需要额外添加依赖我使用的是 JDK 11,所以需要自己添加依赖使用 @Inject 注解。
3、在 service 包下新建一个 UserService 接口在 impl 包下新建一个 UserServiceImpl 实现类
UserService 接口
public interface UserService {
void save();
}
UserServiceImpl 实现类
@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {
@Override
public void save() {
log.info("添加用户.....");
}
}
4、在 controller 包下新建 UserController 类使用 @RequiredArgsConstructor 注解
@Controller
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
public void addUser() {
userService.save();
}
}
这是一个示例的Java类使用了Spring框架中的注解来实现依赖注入和控制反转IoC。
在这个示例中
UserController
是一个控制器类使用了@Controller
注解来标识它是一个控制器组件。@RequiredArgsConstructor
注解是Lombok库提供的用来自动生成构造函数并注入依赖。
UserController
类有一个私有字段userService
通过final
关键字标记并在构造函数中进行初始化。这里使用了构造函数注入即通过构造函数将UserService
的实例注入到UserController
中实现了依赖注入。在
addUser
方法中调用了userService.save()
方法。由于userService
字段已经通过必要的构造函数注入因此可以直接使用userService
对象调用其中的方法。整体而言这段代码展示了基于Spring框架的控制器类定义和依赖注入的方式。通过使用相应的注解可以方便地管理和注入依赖对象实现松耦合的组件之间的协作。
lombook 迎合了 spring 4.2 的新特性实现了更加简洁的注入方式使用 @RequiredArgsConstructor 注解lombook 会自动添加一个带参的构造方法实现构造器的注入注意此时的字段必须是final 修饰
5、在 resources 下新建一个 spring 的 xml 文件 application.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: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:component-scan base-package="edu.nf.ch09"/>
</beans>
6、测试
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserController bean = context.getBean(UserController.class);
bean.addUser();
}
}
运行结果
二、使用 @inject、@Named 注解
1、在 service 包下的 impl 包下在新建一个 StuServiceImpl 实现类
@Slf4j
@Service("stuService")
public class StuServiceImpl implements UserService {
@Override
public void save() {
log.info("添加学生......");
}
}
2、使用 setter 方法注入
@Controller
public class UserController {
private final UserService userService;
/**
* 当有多个实现类并且方法参数与 id 不一致时
* 可以结合 @Named 注解来指定 bean 的 id 又或者
* 可以使用 @Primary 注解设置注入的优先级
*
* @param aa
*/
@Inject
@Named("userService")
public UserController(UserService aa) {
this.userService = aa;
}
public void addUser() {
userService.save();
}
}
上述代码是一个使用了
@Inject
和@Named
注解进行依赖注入的示例涉及到多个实现类时可以使用@Named
注解来指定要注入的实现类的bean的id。
@Inject
是Java依赖注入规范中定义的注解用于在运行时自动注入需要的实例。在使用@Inject注解时可以结合使用@Named注解来指定要注入的实例的bean的id这样Spring框架就可以根据指定的bean id来选择对应的实例进行注入。在上面的示例中
UserController
类被标记为@Controller
组件用于处理HTTP请求。UserService
字段被声明为final
并在构造函数中通过@Inject
和@Named
注解进行注入。使用@Named("userService")
可以指定要注入的bean为id为"userServie"的bean。在addUser()
方法中直接调用userService.save()
方法即可使用该对象提供的服务。整体来说使用注解进行依赖注入的好处是可以避免手动管理对象依赖关系从而减少与依赖相关的代码量和复杂度并且避免由于错误的依赖关系引起的运行时异常。
3、测试
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserController bean = context.getBean(UserController.class);
bean.addUser();
}
}
运行结果
那如果要调用 StudentServiceImpl 实现类的方法呢很简单只需要把 @Named 的值改为注入的bean为id为"stuService"的bean 即可。
三、使用 @RequiredArgsConstructor、@Inject、@Named 有什么好处
@RequiredArgsConstructor
、@Inject
和@Named
这些注解在依赖注入中可以提供以下好处
@RequiredArgsConstructor
注解该注解是Lombok库提供的注解用于自动生成构造函数其中参数为被声明为final或者被标记为@NonNull
的字段。使用该注解可以简化代码省略手动编写构造函数的过程从而提高开发效率。
@Inject
注解该注解是Java依赖注入JSR-330规范中定义的注解用于在运行时自动注入所需的实例。使用该注解可以避免手动处理对象的依赖关系框架会自动将所需的实例注入到相应的位置。这样可以减少与依赖相关的代码量和复杂度并且降低耦合度使代码更加可维护和可测试。
@Named
注解该注解也是Java依赖注入JSR-330规范中定义的注解用于为bean指定唯一的名称或id。当存在多个实现类时可以使用@Named
注解来标识不同的实现类然后在注入时根据指定的bean名称进行选择注入哪个实例。使用@Named
注解可以更精确地控制依赖注入的目标对象提高灵活性。
综上所述使用@RequiredArgsConstructor
可以简化构造函数的编写提高代码效率@Inject
可以自动注入依赖减少手动管理对象依赖关系的代码量和复杂度@Named
可以为bean指定唯一的名称或id使得在存在多个实现类时更精确地控制注入目标。这些注解能够有效地提高代码的可读性、可维护性和可测试性同时减少出错的可能性。