框架-Spring知识点

1.Filter过滤器和Intecepter拦截器的区别

作用范围不同
过滤器属于JavaWeb.它实现的是javax.servlet.Filter接口,这个接口是在Servlet规范中定义的,所以Filter依赖于Tomcat等web容器,只能在web程序中使用
拦截器属于Spring.它是一个Spring的组件,由Spring容器管理,并不依赖Tomcat等容器,可以单独使用,不仅能用于web程序,也可以用于Application和Swing等程序中

触发位置不同
请求->Fileter->Servlet->Intecepter->Controller->响应

实现原理不同
过滤器是基于函数回调的
拦截器是基于Java的反射机制(动态代理)实现的。


2.Constructor注入Setter注入Field注入的区别

今天在油管看视频的时候,一个油管主写了一行注释,不是很理解

better use constructor injection

解答如下:

  1. Field注入
    1
    2
    3
    4
    5
    6
    7
    @Controller
    public class HelloController {
    @Autowired
    private AlphaService alphaService;
    @Autowired
    private BetaService betaService;
    }
    field 注入方式是使用最多的,原因是这种方式使用起来非常简单,代码更加简洁。
  2. Setter 注入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Controller
    public class HelloController {
    private AlphaService alphaService;
    private BetaService betaService;

    @Autowired
    public void setAlphaService(AlphaService alphaService) {
    this.alphaService = alphaService;
    }
    @Autowired
    public void setBetaService(BetaService betaService) {
    this.betaService = betaService;
    }
    }

在 Spring 3.x 刚推出的时候,Spring 官方在对比构造器注入和 Setter 注入时,推荐使用 Setter 方法注入:
Spring 3.x Constructor-based or setter-based DI?

The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is a compelling use case.
Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.

意思是说,当出现很多注入项的时候,构造器参数可能会变得臃肿,特别是当参数时可选的时候。Setter 方式注入可以让类在之后重新配置和重新注入;

  1. Construct注入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Controller
    public class HelloController {
    private final AlphaService alphaService;
    private final BetaService betaService;

    @Autowired
    public HelloController(AlphaService alphaService, BetaService betaService) {
    this.alphaService = alphaService;
    this.betaService = betaService;
    }
    }

Spring 4.x 的时候,Spring 官方在对比构造器注入和 Setter 注入时,推荐使用构造器注入方式:
Spring 4.x Constructor-based or setter-based DI?

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.

因为使用构造器注入方式注入的组件不可变,且保证了需要的依赖不为 null。此外,构造器注入的组件总是能够在完全初始化的状态返回给客户端(调用方);对于很多参数的构造器说明可能包含了太多了职责,违背了单一职责原则,表示代码应该重构来分离职责到合适的地方。

总结

Setter注入应该被用于可选依赖项。当没有提供它们时,类应该能够正常工作。在对象被实例化之后,依赖项可以在任何时候被更改。 m
Constructor注入有利于强制依赖。通过在构造函数中提供依赖,您可以确保依赖对象在被构造时已准备好被使用。在构造函数中赋值的字段也可以是final的,这使得对象是完全不可变的,或者至少可以保护其必需的字段。还可以避免 Field 注入的循环依赖问题,比如 在 Alpha 中注入 Beta,又在 Beta 中注入 Alpha。如果使用构造器注入,在 Spring 启动的时候就会抛出 BeanCurrentlyInCreationException 提醒循环依赖。


Author

Yunzilla

Posted on

2021-09-15

Updated on

2021-09-16

Licensed under

Comments