学习如何编写Spring Field Injection 示例。字段注入是Spring Frameworks依赖注入的一种。在本教程中,我们将编写几个类并查看热门的 Field Injection Works。
更多关于 Spring 依赖注入:
- Spring Setter 依赖注入示例
- Spring 构造函数依赖注入示例
- Spring 依赖注入 – Field vs Setter vs Constructor Injection
- Spring依赖注入和控制反转
基于字段的依赖注入
在这种类型的依赖注入中,Spring 将依赖项直接分配给字段。它不同于Constructor Injection或Setter based Dependency Injection。
有趣的是,Spring 会注入依赖项,即使该字段是私有的。Spring 使用Java 反射来做到这一点。因此,许多专家将其称为不安全。
字段注入可能是最简单(但有风险)的依赖注入形式。为了更好地理解它,我们假设我们有一个正在运行的Spring Boot Service。它是一个用于理解 Field Injection 的虚拟服务。
不知道如何编写 Spring Boot Rest Service?
阅读本文:
Spring Boot Rest 服务
想了解更多关于 Spring 框架的信息吗?
读这个:
- Spring框架介绍
- 春天架构
- 弹簧@Autowired
- Spring中的@Autowired注解
让我们先编写我们的 DogsService 类
狗服务
这个类依赖于DogsDao. 如用 注释的引用变量@Autowired。有一个setter和两个带有各自打印消息的构造函数。
import com.amitph.spring.dogs.dao.DogsDao;
import com.amitph.spring.dogs.repo.Dog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class DogsService {
@Autowired
private DogsDao dao;
public List<Dog> getDogs() {
System.out.println("DogsService.getDogs called");
return dao.getAllDogs();
}
public void setDao(DogsDao dao) {
System.out.println("DogsService setter called");
this.dao = dao;
}
public DogsService(){
System.out.println("DogsService no-arg constructor called");
}
public DogsService(DogsDao dao) {
System.out.println("DogsService arg constructor called");
this.dao = dao;
}
}
狗控制器
Controller 依赖于DogsService. 与服务类类似,注释@Autowired被添加到引用变量中。有带有打印消息的设置器和构造器。
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.service.DogsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/dogs")
public class DogsController {
@Autowired
private DogsService service;
@GetMapping
public List<Dog> getDogs() {
return service.getDogs();
}
public void setService(DogsService service) {
System.out.println("DogsController setter called");
this.service = service;
}
public DogsController(){
System.out.println("DogsController no-arg constructor called");
}
public DogsController(DogsService service) {
System.out.println("DogsController arg constructor called");
this.service = service;
}
}
运行代码
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.0.RELEASE)
2019-02-05 06:34:14.956 INFO 69421 --- [ main] com.amitph.spring.dogs.Application : Starting Application on Amits-office-mac.local with PID 69421 (/Users/aphaltankar/Workspace/personal/dog-service-jpa/out/production/classes started by aphaltankar in /Users/aphaltankar/Workspace/personal/dog-service-jpa)
2019-02-05 06:34:14.957 INFO 69421 --- [ main] com.amitph.spring.dogs.Application : No active profile set, falling back to default profiles: default
2019-02-05 06:34:15.655 INFO 69421 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-02-05 06:34:15.711 INFO 69421 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 50ms. Found 1 repository interfaces.
2019-02-05 06:34:16.013 INFO 69421 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$EnhancerBySpringCGLIB$1cc57cd7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-02-05 06:34:16.318 INFO 69421 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-02-05 06:34:16.335 INFO 69421 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-02-05 06:34:16.335 INFO 69421 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.12
2019-02-05 06:34:16.342 INFO 69421 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/aphaltankar/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2019-02-05 06:34:16.429 INFO 69421 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-02-05 06:34:16.429 INFO 69421 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1419 ms
2019-02-05 06:34:16.454 INFO 69421 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2019-02-05 06:34:16.457 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-02-05 06:34:16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-02-05 06:34:16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'formContentFilter' to: [/*]
2019-02-05 06:34:16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2019-02-05 06:34:16.581 INFO 69421 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-02-05 06:34:16.702 INFO 69421 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-02-05 06:34:16.830 INFO 69421 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2019-02-05 06:34:16.906 INFO 69421 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.3.7.Final}
2019-02-05 06:34:16.907 INFO 69421 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2019-02-05 06:34:17.059 INFO 69421 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2019-02-05 06:34:17.188 INFO 69421 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
2019-02-05 06:34:17.783 INFO 69421 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
DogsDao no-arg constructor called
DogsService no-arg constructor called
DogsController no-arg constructor called
2019-02-05 06:34:18.208 INFO 69421 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-02-05 06:34:18.244 WARN 69421 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-02-05 06:34:18.420 INFO 69421 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-02-05 06:34:18.422 INFO 69421 --- [ main] com.amitph.spring.dogs.Application
所有三个无参数控制器按顺序调用。没有调用setter或参数化构造函数。还要注意的另一件事是标记@Autowired为private的字段。
Spring可以设置私有字段
Spring 使用反射在我们的对象上设置私有字段。这听起来很有用,但另一方面也不安全。现场注入,它的安全性和实用性一直备受争议。Spring 不尊重对象访问规则。现在,有些人可能支持这一点,或者说 Spring IoC 容器管理所有对象,并且应该对对象进行最高控制。
@Component
public class MyClass {
@Autowired private DogsController controller;
@Autowired private DogsService service;
@Autowired private DogsDao dao;
@Autowired private ApplicationProperties properties;
/ business methods
}
作为一名开发人员,我一直喜欢使用 Field Injection,因为它非常简单且更具可读性。您实际上可以避免编写setter 方法或构造函数,而专注于业务方法。
概括
您了解到Field Injection是Spring Dependency Injection的一种,并编写了几个类来查看它的工作原理。字段注入很简单,并且使类更具可读性。然而,由于它的安全问题,许多人讨厌它并避免使用它。
在接下来的部分中,我们将看到Setter Injection、Field Injection和Constructor Injection这三者之间的详细区别。
快乐编码!
最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!