Spring 字段依赖注入示例

学习如何编写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 InjectionSpring Dependency Injection的一种,并编写了几个类来查看它的工作原理。字段注入很简单,并且使类更具可读性。然而,由于它的安全问题,许多人讨厌它并避免使用它。

在接下来的部分中,我们将看到Setter InjectionField InjectionConstructor Injection这三者之间的详细区别。

快乐编码!

最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值