Documentation-Spring_Core_IOC

  1. 🌟introduction (介绍)
    1. BeanFactory
    2. ApplicationContext
    3. Beans
  2. 🌟Container overview (容器预览)
    1. configuration metadata (配置元信息)
    2. Instantiating a Container (实例化容器)
    3. Using the Container (使用容器)
  3. 🌟Bean Overview (bean 预览)
    1. beanDefinition(bean定义)
    2. naming bean (bean命名)
      1. Aliasing a Bean outside the Bean Definition
    3. Instantiating bean (bean构造方式)
      1. Instantiation with a Constructor
      2. Instantiation with a Static Factory Method
      3. Instantiation by Using an Instance Factory Method
  4. 🌟Dependencies (依赖)
    1. Dependency Injection(DI)
      1. Constructor-based Dependency Injection(构造注入)
      2. Setter-based Dependency Injection(Setter注入)
      3. Dependency Resolution Process (依赖解析过程)
        1. Circular dependencies (循环依赖问题)
        2. pre-instantiate (预实例化可以提早发现错误)
        3. collaborating (被装载的是完整实例)
      4. Examples of Dependency Injection
    2. Dependencies and Configuration in Detail
    3. Using depends-on (使用 depends-on)
    4. Lazy-initialized Beans (懒加载)
    5. Autowiring Collaborators(自动装配)
      1. Limitations and Disadvantages of Autowiring (自动装配的局限性和缺点)
      2. Excluding a Bean from Autowiring(从自动装配中排除Bean)
    6. Method Injection (方法注入)
      1. Lookup Method Injection
      2. Arbitrary (任意的)Method Replacement
  5. 🌟Bean Scopes (作用域)
    1. The Singleton Scope
    2. The Prototype Scope
    3. Singleton Beans with Prototype-bean Dependencies
    4. Request, Session, Application, and WebSocket Scopes
      1. Request scope
      2. Session Scope
      3. Application Scope
      4. Scoped Beans as Dependencies
    5. Custom Scopes
  6. 🌟Customizing the Nature of a Bean(bean扩展点)
    1. Lifecycle Callbacks (生命周期回调)
      1. Initialization Callbacks
      2. Destruction Callbacks
      3. Default Initialization and Destroy Methods
      4. Combining Lifecycle Mechanisms
      5. Startup and Shutdown Callbacks
        1. Lifecycle
        2. LifecycleProcessor
        3. Phased
      6. Shutting Down the Spring IoC Container Gracefully in Non-Web Applications
    2. ApplicationContextAware and BeanNameAware
      1. ApplicationContextAware
      2. BeanNameAware
    3. Other Aware Interfaces
  7. Bean Definition Inheritance (定义继承)
  8. 🌟Container Extension Points (容器扩展点)
    1. Customizing Beans by Using a BeanPostProcessor
    2. Customizing Configuration Metadata with a BeanFactoryPostProcessor
      1. PropertySourcesPlaceholderConfigurer
      2. PropertyOverrideConfigurer
    3. Customizing Instantiation Logic with a FactoryBean
  9. 🌟Annotation-based Container Configuration (基于注释的容器配置)
    1. @Required
    2. Using @Autowired
      1. @Order
      2. Java8 & spring 5.0
    3. Fine-tuning(微调) Annotation-based Autowiring with @Primary
    4. Fine-tuning Annotation-based Autowiring with Qualifiers
    5. Using Generics as Autowiring Qualifiers
    6. Using CustomAutowireConfigurer
    7. Injection with @Resource (JSR-250 & name)
    8. Using @Value
    9. Using @PostConstruct and @PreDestroy (JSR-250)
  10. 🌟Classpath Scanning and Managed Components
    1. @Component and Further Stereotype Annotations (模式注解)
    2. Using Meta-annotations and Composed Annotations(元注解)
    3. Automatically Detecting Classes and Registering Bean Definitions(自动检测类并注册Bean定义)
    4. Using Filters to Customize Scanning
    5. Defining Bean Metadata within Components(在组件中定义Bean元数据)
    6. Naming Autodetected Components(命名自动检测的组件)
      1. Providing a Scope for Autodetected Components(提供自动检测组件的作用域)
      2. Providing Qualifier Metadata with Annotations
      3. Generating an Index of Candidate Components(生成候选组件的索引)
  11. 🌟Using JSR 330 Standard Annotations
    1. Dependency Injection with @Inject and @Named
    2. @Named and @ManagedBean: Standard Equivalents to the @Component Annotation(@Component注解的比较)
    3. Limitations of JSR-330 Standard Annotations
  12. 🌟Java-based Container Configuration(基于Java的容器配置)
    1. Basic Concepts: @Bean and @Configuration
    2. Instantiating the Spring Container by Using AnnotationConfigApplicationContext
    3. Using the @Bean Annotation
    4. Using the @Configuration annotation
    5. Composing Java-based Configurations
    6. Using the @Import Annotation
    7. Conditionally Include @Configuration Classes or @Bean Methods
    8. Combining Java and XML Configuration
      1. XML-centric Use of @Configuration Classes
      2. @ConfigurationClass-centric Use of XML with@ImportResource
  13. 🌟Environment Abstraction (环境抽象)
    1. Bean Definition Profiles
      1. Using @Profile
      2. XML Bean Definition Profiles
      3. Activating a Profile
      4. Default Profile
    2. PropertySource Abstraction
    3. Using @PropertySource
    4. Placeholder Resolution in Statements
  14. 🌟Registering a LoadTimeWeaver
  15. 🌟Additional Capabilities of the ApplicationContext (BeanFactory的扩展)
    1. Internationalization using MessageSource
    2. Standard and Custom Events
      1. Annotation-based Event Listeners
      2. Asynchronous Listeners
      3. Ordering Listeners
      4. Generic Events
    3. Convenient Access to Low-level Resources
    4. Convenient ApplicationContext Instantiation for Web Applications
    5. Deploying a Spring ApplicationContext as a Java EE RAR File
  16. 🌟The BeanFactory
    1. BeanFactory or ApplicationContext?
  17. 总览

关键字: bean(定义-关系、 加载方式(创建、解析) 、扩展)、application(容器、resource、加载、扩展)、注解、环境(Environment)

Tips: 在看官方文档时候的一些摘抄、总结(建议直接阅读官方文档

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans

Version 5.2.1.RELEASE )

IOC 容器(DI 查找和注入)

​ —> Bean管理 (关系、作用域、生命周期、扩展点)

​ —> Bean元信息(属性值)

基础设施扩展 (资源管理 类型 事件等)

🌟introduction (介绍)

关键词: BeanFactory、ApplicationContext (App internationalization 、event 、web)、beans

This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle.

IoC is also known as dependency injection (DI)

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container.

BeanFactory

The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object

提供了一种能够管理任何类型对象的高级配置机制

ApplicationContext

ApplicationContext

  • Easier integration with Spring’s AOP features (和AOP更好集成)
  • Message resource handling (for use in internationalization)
  • Event publication (事件发布机制)
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

Beans

A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.

Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

bean是由Spring IoC容器实例化、组装和管理的对象。

bean及其之间的依赖关系反映在容器使用的配置元数据中。

🌟Container overview (容器预览)

关键词: configuration metadata、Instantiating

container magic

configuration metadata (配置元信息)

The configuration metadata is represented in XML, Java annotations, or Java code.

annotations

  • spring 2.5 annotation-based
  • spring 3.0 java-based Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framework. Thus, you can define beans external to your application classes by using Java rather than XML files. To use these new features, see the @Configuration, @Bean, @Import, and @DependsOn annotations.

Instantiating a Container (实例化容器)

提供给“ApplicationContext”构造函数的位置路径是资源字符串,它允许容器从各种外部资源(如本地文件系统、Java“CLASSPATH”等)加载配置元数据。

Using the Container (使用容器)

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

🌟Bean Overview (bean 预览)

bean的一个介绍

关键词: beanDefinition、instantiating、Naming

beanDefinition(bean定义)

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

  • A package-qualified class name: typically, the actual implementation class of the bean being defined.(名字)
  • Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth). (状态、行为)
  • References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies. (依赖关系)
  • Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.
Property Explained in…
Class Instantiating Beans
Name Naming Beans
Scope Bean Scopes
Constructor arguments Dependency Injection
Properties Dependency Injection
Autowiring mode Autowiring Collaborators
Lazy initialization mode Lazy-initialized Beans
Initialization method Initialization Callbacks
Destruction method Destruction Callbacks

naming bean (bean命名)

Aliasing a Bean outside the Bean Definition

Instantiating bean (bean构造方式)

You can use the Class property in one of two ways:

  • Typically, to specify the bean class to be constructed in the case where the container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code with the new operator.
  • To specify the actual class containing the static factory method that is invoked to create the object, in the less common case where the container invokes a static factory method on a class to create the bean. The object type returned from the invocation of the static factory method may be the same class or another class entirely.

Instantiation with a Constructor

Spring IoC容器几乎可以管理您希望它管理的任何类。它不仅限于管理真正的javabean。

大多数Spring用户更喜欢实际的javabean,它只有一个默认的(无参数的)构造函数,以及根据容器中的属性建模的适当的setter和getter方法。

您还可以在容器中包含更多非bean风格的类。例如,如果您需要使用完全不符合JavaBean规范的遗留连接池,Spring也可以管理它。

Instantiation with a Static Factory Method

这种bean定义的一个用途是在遗留代码中调用“静态”工厂。

Instantiation by Using an Instance Factory Method

与通过静态工厂方法实例化类似,使用实例工厂方法实例化将从容器中调用现有bean的非静态方法来创建新bean。

In Spring documentation, “factory bean” refers to a bean that is configured in the Spring container and that creates objects through an instance or static factory method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-specific FactoryBean.

在Spring文档中,“工厂bean”指的是在Spring容器中配置的bean,它通过实例或静态工厂方法创建对象。相反,FactoryBean(注意大小写)指的是特定于spring的FactoryBean。

🌟Dependencies (依赖)

更多描述的是bean之间的关系

关键词: IOC、DI、collaborate(协作者)、 construct-b(type index name)、 setter-b 、解析过程、循环依赖、提前实例、自动装配、方法注入

典型的企业应用程序不包含单个对象(或Spring中的bean)。即使是最简单的应用程序也有几个对象一起工作,以呈现最终用户所看到的一致的应用程序。

下一节将解释如何从定义许多独立的bean定义过渡到一个完全实现的应用程序,其中对象通过协作实现目标。

Dependency Injection(DI)

使用DI原则,代码更简洁,并且当对象提供其依赖项时,解耦更有效。对象不查找其依赖项,也不知道依赖项的位置或类。

Constructor-based Dependency Injection(构造注入)

  • Constructor argument type matching
  • Constructor argument index
  • Constructor argument name

Setter-based Dependency Injection(Setter注入)

基于setter的DI是在调用无参数构造函数或无参数“静态”工厂方法来实例化bean之后,通过容器调用bean上的setter方法来完成的。

您可以将依赖项配置为“BeanDefinition”的形式,并将其与“PropertyEditor”实例结合使用,将属性从一种格式转换为另一种格式。

但是,大多数Spring用户并不直接使用这些类(也就是说,以编程的方式),而是使用XML ‘ bean ‘定义、带注释的组件(也就是说,使用’ @Component ‘、’ @Controller ‘等注释的类)或基于java的’ @Configuration ‘类中的’ @Bean ‘方法。

然后,这些源在内部转换为“BeanDefinition”实例,并用于加载整个Spring IoC容器实例。

Constructor-based or setter-based DI?

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable.

The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the 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.

Dependency Resolution Process (依赖解析过程)

ApplicationContext(configuration metadata) -> 注入方式 -> 注入value初始化 -> value-type

The container performs bean dependency resolution as follows:

  • The ApplicationContext is created and initialized with configuration metadata that describes all the beans. Configuration metadata can be specified by XML, Java code, or annotations.(配置元信息)
  • For each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method (if you use that instead of a normal constructor). These dependencies are provided to the bean, when the bean is actually created. (注入方式)
  • Each property or constructor argument is an actual definition of the value to set, or a reference to another bean in the container.(value)
  • Each property or constructor argument that is a value is converted from its specified format to the actual type of that property or constructor argument. By default, Spring can convert a value supplied in string format to all built-in types, such as int, long, String, boolean, and so forth.(value-type)
Circular dependencies (循环依赖问题)

If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection.

If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.

One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only.

In other words, although it is not recommended, you can configure circular dependencies with setter injection.

如果主要使用构造函数注入,可能会创建无法解析的循环依赖场景。

例如:类A需要一个类B通过构造函数注入的实例,而类B需要一个类A通过构造函数注入的实例。

如果您将bean配置为类A和B相互注入,Spring IoC容器会在运行时检测到这个循环引用,并抛出一个“BeanCurrentlyInCreationException”。

一种可能的解决方案是编辑某些类的源代码,由setter而不是构造函数来配置。另外,避免构造函数注入,只使用setter注入。

换句话说,尽管不建议这样做,但您可以使用setter注入配置循环依赖项。

pre-instantiate (预实例化可以提早发现错误)

这可能会延迟某些配置问题的可见性,这就是为什么默认情况下ApplicationContext实现会预先实例化单例bean的原因。

在实际需要使用这些bean之前要花一些前期时间和内存,您会在创建ApplicationContext时发现配置问题,而不是稍后。

collaborating (被装载的是完整实例)

如果不存在循环依赖项,那么当一个或多个协作bean被注入一个依赖bean时,每个协作bean在被注入依赖bean之前都要完全配置好。

这意味着,如果bean A依赖于bean B,那么Spring IoC容器将在调用bean A的setter方法之前完全配置bean B。

换句话说,bean被实例化(如果它不是一个预实例化的单例对象),它的依赖项被设置,相关的生命周期方法(例如配置的init方法或InitializingBean回调方法)被调用。

Examples of Dependency Injection

Dependencies and Configuration in Detail

Using depends-on (使用 depends-on)

能控制加载顺序

Lazy-initialized Beans (懒加载)

默认情况下,“ApplicationContext”实现会在初始化过程中创建并配置所有的单例bean。

通常,这种预实例化是可取的,因为配置或周围环境中的错误会立即被发现,而不是几小时甚至几天之后。

当此行为不可取时,您可以通过将bean定义标记为延迟初始化来防止单例bean的预实例化。延迟初始化的bean告诉IoC容器在第一次请求时创建bean实例,而不是在启动时。

但是,如果延迟初始化的bean是未延迟初始化的单例bean的依赖项,则ApplicationContext会在启动时创建延迟初始化的bean,因为它必须满足单例的依赖项。延迟初始化的bean被注入到其他未延迟初始化的单例bean中。

另外还可以容器级别的配置懒加载

注:使用@Lazy , 在需要注入到其他not lazy的bean的时候 使用@Autowire的话 在上面标注@Lazy 会延迟初始化

@Lazy
@Component
class LazyBean{
   @PostConstruct
           public void init(){
               System.out.prinlt("init...");
           }
}
@Component
class NotLazyBean{
       @Lazy
       @Autowise
               LazyBean lazyBean;
}

会在实际使用lazyBean的时候才实例

Autowiring Collaborators(自动装配)

Autowiring has the following advantages:

  • Autowiring can significantly reduce the need to specify properties or constructor arguments. (Other mechanisms such as a bean template discussed elsewhere in this chapter are also valuable in this regard.)
  • Autowiring can update a configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without you needing to modify the configuration. Thus autowiring can be especially useful during development, without negating the option of switching to explicit wiring when the code base becomes more stable.

译:

  • 自动装配可以大大减少指定属性或构造函数参数的需要。(其他机制,如bean模板[在本章其他地方讨论过](https://docs.spring.io/spring-framework/docs/current/spring-framereference/core.html #beans-child-bean-definitions)在这方面也很有价值。)
  • 自动装配可以随着对象的演化更新配置。例如,如果需要向类添加依赖项,则可以自动满足该依赖项,而不需要修改配置。因此,自动装配在开发过程中特别有用,当代码库变得更加稳定时,自动装配可以避免切换到显式连接的选项。
Mode Explanation
no (Default) No autowiring. Bean references must be defined by ref elements. Changing the default setting is not recommended for larger deployments, because specifying collaborators explicitly gives greater control and clarity. To some extent, it documents the structure of a system.
byName Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master and uses it to set the property.
byType Lets a property be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens (the property is not set).
constructor Analogous to byType but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.

Limitations and Disadvantages of Autowiring (自动装配的局限性和缺点)

Consider the limitations and disadvantages of autowiring:

  • Explicit dependencies in property and constructor-arg settings always override autowiring. You cannot autowire simple properties such as primitives, Strings, and Classes (and arrays of such simple properties). This limitation is by-design.
  • Autowiring is less exact than explicit wiring. Although, as noted in the earlier table, Spring is careful to avoid guessing in case of ambiguity that might have unexpected results. The relationships between your Spring-managed objects are no longer documented explicitly.
  • Wiring information may not be available to tools that may generate documentation from a Spring container.
  • Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Map instances, this is not necessarily a problem. However, for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.

In the latter scenario, you have several options:

  • Abandon autowiring in favor of explicit wiring.
  • Avoid autowiring for a bean definition by setting its autowire-candidate attributes to false, as described in the next section.
  • Designate a single bean definition as the primary candidate by setting the primary attribute of its <bean/> element to true.
  • Implement the more fine-grained control available with annotation-based configuration, as described in Annotation-based Container Configuration.

使用自动装配 ,可能不那么精确, 会导致一些问题

Excluding a Bean from Autowiring(从自动装配中排除Bean)

在每个bean的基础上,可以将bean排除在自动装配之外。在Spring的XML格式中,将“”元素的“autowire-candidate”属性设置为“false”。容器使特定的bean定义对自动装配基础设施不可用(包括注释样式配置,如[‘ @Autowired ‘](https://docs.spring.io/spring-framework/docs/current/spring-framereference/core.html #beans-autowired-annotation))。

Method Injection (方法注入)

假设单例bean A需要使用非单例(原型)bean B,可能是在A的每个方法调用上。容器只创建一次单例bean A,因此只有一次机会来设置属性。

解决的办法是放弃一些控制反转。您可以通过实现applicationcontext - ware接口,并在每次bean A需要时调用容器的getBean(“B”)来请求(通常是一个新的)bean B实例,从而使bean A知道容器。

Lookup Method Injection

查找方法注入是容器覆盖容器管理bean上的方法 并返回容器中另一个命名bean的查找结果的能力。

Spring框架通过使用来自CGLIB库的字节码生成来动态生成覆盖该方法的子类,从而实现了这种方法注入。

ex

Arbitrary (任意的)Method Replacement

与查找方法注入相比,一种不太有用的方法注入形式是能够用另一种方法实现替换托管bean中的任意方法。

🌟Bean Scopes (作用域)

关键词: singleton、prototype、request、session、application、websocket 、cglib public

您不仅可以控制要插入到由特定bean定义创建的对象中的各种依赖项和配置值,还可以控制由特定bean定义创建的对象的范围

Scope Description
singleton (Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
prototype Scopes a single bean definition to any number of object instances.
request Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
application Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocket Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

The Singleton Scope

换句话说,当您定义一个bean定义并将其定义为一个单例对象时,Spring IoC容器只创建该bean定义定义的对象的一个实例。

此单一实例存储在此类单例bean的缓存中,该指定bean的所有后续请求和引用都将返回缓存的对象

Spring的单例bean概念与Gang of Four(GoF)模式书中定义的单例模式不同。

单例对象对对象的作用域进行硬编码,这样每个类装入器只能创建一个特定类的实例

The Prototype Scope

通常,您应该为所有有状态bean使用原型范围,为无状态bean使用单例范围。

在某些方面,Spring容器在原型作用域bean方面的作用是替代Java“new”操作符。

Singleton Beans with Prototype-bean Dependencies

Request, Session, Application, and WebSocket Scopes

Request scope

您可以随意更改创建的实例的内部状态,因为从相同的“loginAction”bean定义创建的其他实例在状态中看不到这些更改。

Session Scope

与请求范围内bean一样,你可以改变内部状态的实例创建尽可能多的你想要的,知道其他HTTP会话的实例也使用相同的实例创建的userPreferences bean定义看不到这些变化状态,因为他们是特定的一个单独的HTTP会话的。

Application Scope

这有点类似于spring单例bean,但在两个重要方面不同: 它是一个单例每ServletContext,不是每个spring ApplicationContext的(可能有几个在任何给定的web应用程序),它实际上是暴露,因此可见“ServletContext”属性。

Scoped Beans as Dependencies

Spring IoC容器不仅管理对象(bean)的实例化,还管理协作者(或依赖项)的连接。如果您想将(例如)一个HTTP请求作用域的bean注入到另一个更长的作用域的bean中,您可以选择注入一个AOP代理来代替作用域的bean。

Choosing the Type of Proxy to Create

CGLIB proxies intercept only public method calls! Do not call non-public methods on such a proxy. They are not delegated to the actual scoped target object.

Custom Scopes

🌟Customizing the Nature of a Bean(bean扩展点)

关键词: lifecycle callback; aware;

The Spring Framework provides a number of interfaces you can use to customize the nature of a bean. This section groups them as follows:

Lifecycle Callbacks (生命周期回调)

在内部,Spring框架使用“BeanPostProcessor”实现来处理它能找到并调用适当方法的任何回调接口。如果您需要自定义特性或Spring默认不提供的其他生命周期行为,您可以自己实现一个“BeanPostProcessor”。有关更多信息,请参见[容器扩展点](https://docs.spring.io/spring-framework/docs/current/spring-framereference/core.html #beans-factory-extension)。

  • spring 接口 耦合 InitializingBeanDisposableBean
  • JSR-250 @PostConstruct 或 init-method @PreDestroy或 destroy-method
  • Lifecycle

Initialization Callbacks

public class AnotherExampleBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        // do some initialization work
    }
}

Destruction Callbacks

public class AnotherExampleBean implements DisposableBean {

    @Override
    public void destroy() {
        // do some destruction work (like releasing pooled connections)
    }
}

Default Initialization and Destroy Methods

  • default-init-method
  • default-destroy-method

Combining Lifecycle Mechanisms

As of Spring 2.5, you have three options for controlling bean lifecycle behavior:

Startup and Shutdown Callbacks

Lifecycle
public interface Lifecycle {

    void start();

    void stop();

    boolean isRunning();
}
LifecycleProcessor
public interface LifecycleProcessor extends Lifecycle {

    void onRefresh();

    void onClose();
}
Phased

启动和关闭调用的顺序可能很重要。如果任何两个对象之间存在“依赖关系”,依赖方在依赖后开始,在依赖前停止。然而,有时,直接依赖关系是未知的。您可能只知道某种类型的对象应该先于另一种类型的对象启动。

public interface Phased {

    int getPhase();
}

Shutting Down the Spring IoC Container Gracefully in Non-Web Applications

如果您在非web应用程序环境(例如,在客户机桌面环境中)中使用Spring的IoC容器,请向JVM注册一个关闭挂钩。这样做可以确保优雅地关闭并调用单例bean上的相关销毁方法,以便释放所有资源。您仍然必须正确配置和实现这些销毁回调。

registerShutdownHook()

ApplicationContextAware and BeanNameAware

ApplicationContextAware

public interface ApplicationContextAware {

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

BeanNameAware

public interface BeanNameAware {

    void setBeanName(String name) throws BeansException;
}

Other Aware Interfaces

Name Injected Dependency Explained in…
ApplicationContextAware Declaring ApplicationContext. ApplicationContextAware and BeanNameAware
ApplicationEventPublisherAware Event publisher of the enclosing ApplicationContext. Additional Capabilities of the ApplicationContext
BeanClassLoaderAware Class loader used to load the bean classes. Instantiating Beans
BeanFactoryAware Declaring BeanFactory. ApplicationContextAware and BeanNameAware
BeanNameAware Name of the declaring bean. ApplicationContextAware and BeanNameAware
BootstrapContextAware Resource adapter BootstrapContext the container runs in. Typically available only in JCA-aware ApplicationContext instances. JCA CCI
LoadTimeWeaverAware Defined weaver for processing class definition at load time. Load-time Weaving with AspectJ in the Spring Framework
MessageSourceAware Configured strategy for resolving messages (with support for parametrization and internationalization). Additional Capabilities of the ApplicationContext
NotificationPublisherAware Spring JMX notification publisher. Notifications
ResourceLoaderAware Configured loader for low-level access to resources. Resources
ServletConfigAware Current ServletConfig the container runs in. Valid only in a web-aware Spring ApplicationContext. Spring MVC
ServletContextAware Current ServletContext the container runs in. Valid only in a web-aware Spring ApplicationContext. Spring MVC

再次注意,使用这些接口将您的代码绑定到Spring API,并且不遵循控制反转样式。因此,我们建议将它们用于需要对容器进行编程访问的基础设施bean。

Bean Definition Inheritance (定义继承)

🌟Container Extension Points (容器扩展点)

关键词 : bean; beanPostProcessor;Metadata ;BeanFactoryPostProcessor;FactoryBean; scoped per-container

Customizing Beans by Using a BeanPostProcessor

//一般用于自定义构造bean, 处理注解 (通用注解 和 自定义注解)

BeanPostProcessor接口定义了回调方法,您可以实现这些回调方法来提供自己的(或覆盖容器的默认)实例化逻辑、依赖项解析逻辑等等。

如果希望在Spring容器完成实例化、配置和初始化bean之后实现一些自定义逻辑,可以插入一个或多个自定义BeanPostProcessor实现。

您可以配置多个BeanPostProcessor实例,并且可以通过设置order属性来控制这些BeanPostProcessor实例的执行顺序。只有在BeanPostProcessor实现有序接口时才能设置此属性。

org.springframework.beans.factory.config。BeanPostProcessor接口正好由两个回调方法组成。

当这样一个类注册为后处理器的容器,每个容器创建bean实例,后处理器从容器之前得到一个回调容器初始化方法(如InitializingBean.afterPropertiesSet()或任何宣布init方法),任何bean初始化后回调。

后处理器可以对bean实例采取任何操作,包括完全忽略回调。bean后处理器通常检查回调接口,或者使用代理包装bean。为了提供代理包装逻

BeanPostProcessor instances and AOP auto-proxying

实现“BeanPostProcessor”接口的类是特殊的,容器会以不同的方式对待它们。

它们直接引用的所有“BeanPostProcessor”实例和bean在启动时实例化,作为“ApplicationContext”的特殊启动阶段的一部分。

接下来,以排序的方式注册所有’ BeanPostProcessor ‘实例,并将其应用于容器中所有后续的bean。因为AOP自动代理是作为“BeanPostProcessor”本身实现的,所以无论是“BeanPostProcessor”实例还是它们直接引用的bean都没有资格进行自动代理,因此没有将方面融入到它们之中。

对于任何这样的bean,您应该看到一条信息日志消息:“bean someBean不适合被所有BeanPostProcessor接口处理(例如: not eligible for auto-proxying)”。

public interface BeanPostProcessor {

   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

   @Nullable
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

}

Customizing Configuration Metadata with a BeanFactoryPostProcessor

//一般应用用于配置文件的解析 , 占位符的替换

这个接口的语义与“BeanPostProcessor”的语义类似,但有一个主要区别:“BeanFactoryPostProcessor”操作bean配置元数据。

也就是说,Spring IoC容器允许“BeanFactoryPostProcessor”读取配置元数据,并可能在容器实例化除“BeanFactoryPostProcessor”实例之外的任何bean之前更改它。

您可以配置多个’ BeanFactoryPostProcessor ‘实例,并且可以通过设置’ order ‘属性来控制这些’ BeanFactoryPostProcessor ‘实例的运行顺序。但是,只有在’ BeanFactoryPostProcessor ‘实现’ Ordered ‘接口时才能设置此属性。

@FunctionalInterface
public interface BeanFactoryPostProcessor {

   /**
    * Modify the application context's internal bean factory after its standard
    * initialization. All bean definitions will have been loaded, but no beans
    * will have been instantiated yet. This allows for overriding or adding
    * properties even to eager-initializing beans.
    * @param beanFactory the bean factory used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

Spring includes a number of predefined bean factory post-processors, such as PropertyOverrideConfigurer and PropertySourcesPlaceholderConfigurer.

PropertySourcesPlaceholderConfigurer

在运行时,’ PropertySourcesPlaceholderConfigurer ‘应用于替代数据源的某些属性的元数据。

‘ PropertySourcesPlaceholderConfigurer ‘不仅在您指定的’ properties ‘文件中查找属性。默认情况下,如果在指定的属性文件中找不到属性,它会检查Spring的“Environment”属性和常规的Java“System”属性。

PropertyOverrideConfigurer

另一个bean工厂后处理器’ PropertyOverrideConfigurer ‘类似于’ PropertySourcesPlaceholderConfigurer ‘,但与后者不同,原始定义可以有缺省值,也可以没有bean属性的值。

如果覆盖的“属性”文件没有某个bean属性的条目,则使用默认的上下文定义。

Customizing Instantiation Logic with a FactoryBean

FactoryBean接口是一个可插入Spring IoC容器实例化逻辑的点。

如果您有复杂的初始化代码,用Java表示比(可能的)冗长的XML更好,那么您可以创建自己的FactoryBean,在该类中编写复杂的初始化,然后将定制的FactoryBean插入容器中。

The FactoryBean interface provides three methods:

  • Object getObject(): Returns an instance of the object this factory creates. The instance can possibly be shared, depending on whether this factory returns singletons or prototypes.
  • boolean isSingleton(): Returns true if this FactoryBean returns singletons or false otherwise.
  • Class getObjectType(): Returns the object type returned by the getObject() method or null if the type is not known in advance.

当您需要向容器请求实际的“FactoryBean”实例本身而不是它所生成的bean时,

在调用“ApplicationContext”的“getBean()”方法时,在bean的“id”前面加上与符号(“&”)。

🌟Annotation-based Container Configuration (基于注释的容器配置)

🔑关键词: configuration metadata; @Autowired ;@Order;@Primary;@Qulifier;@Resources;BeanPostProcessor

🕙Timeline:

  • Spring 2.0 @required
  • Spring 2.5 @Autowired ,also JSR-250 annotations, such as @PostConstruct and @PreDestroy.
  • Spring 3.0 JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as @Inject and @Named.

how to provide a lot of the configuration metadata through source-level annotations.

如何通过源级别的注解提供许多配置元数据。

can also be implicitly registered by including the following tag in an XML-based Spring configuration

<beans xmlns:context="http://www.springframework.org/schema/context"
       ...>
    <context:annotation-config/>
</beans>

The implicitly registered post-processors include

注解注入在XML注入之前执行。 因此,XML配置将覆盖通过两种方法连接的属性的注释。

@Required

从Spring Framework 5.1开始,正式弃用了@Required批注(弃用),以便使用构造函数注入进行必需的设置(或InitializingBean.afterPropertiesSet()的自定义实现以及bean属性设置器方法)。

Using @Autowired

  • apply the @Autowired annotation to constructors
  • apply the @Autowired annotation to traditional setter methods
  • apply the annotation to methods with arbitrary names and multiple arguments
  • apply @Autowired to fields as well and even mix it with constructors

从Spring Framework 4.3开始,如果目标bean仅定义一个构造函数作为开始,则不再需要在此类构造函数上使用@Autowired批注。

但是,如果有几个构造函数可用,则至少一个必须用@Autowired注释,以指示容器使用哪个构造函数。

⚠️Ps: 自动装配注意 no type match found ,需要确保类型唯一

@Order

您可以在目标类级别和@Bean方法上声明@Order批注,这可能适用于单个bean定义(如果使用同一bean类的多个定义)。 @Order值可能会影响注入点的优先级,但请注意它们不会影响单例启动顺序,这是由依赖关系和@DependsOn声明确定的正交关注点 。

注意,标准javax.annotation.Priority注释在@Bean级别不可用,因为无法在方法上声明它。 它的语义可以通过@Order值与@Primary结合在每种类型的单个bean上进行建模。

Java8 & spring 5.0

express the non-required nature of a particular dependency through Java 8’s java.util.Optional

As of Spring Framework 5.0, you can also use a @Nullable annotation (of any kind in any package — for example, javax.annotation.Nullable from JSR-305)

Spring BeanPostProcessor实现处理@ Autowired,@ Inject,@ Value和@Resource批注。

这意味着您不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型(如果有)中应用这些注释。

Fine-tuning(微调) Annotation-based Autowiring with @Primary

当可以确定一个主要候选者时,@ Primary是在几种情况下按类型使用自动装配的有效方法。

Fine-tuning Annotation-based Autowiring with Qualifiers

就是说,如果您打算按名称表示注释驱动的注入,则即使它能够在类型匹配的候选对象中按bean名称进行选择,也不要主要使用@ Autowired

相反,请使用JSR-250@ Resource注释,该注释在语义上定义为通过其唯一名称标识特定目标组件,而声明的类型与匹配过程无关。

Using Generics as Autowiring Qualifiers

除了@Qualifier批注之外,您还可以使用Java泛型类型作为资格的隐式形式

Using CustomAutowireConfigurer

CustomAutowireConfigurer是BeanFactoryPostProcessor,即使您没有使用Spring的@Qualifier批注进行批注,也可以让您注册自己的自定义批注批注类型。

@see org.springframework.beans.factory.annotation.CustomAutowireConfigurer

Injection with @Resource (JSR-250 & name)

Spring还通过在字段或bean属性设置器方法上使用JSR-250@ Resource批注(javax.annotation.Resource`)支持注入。

@Resource具有名称属性。 默认情况下,Spring将该值解释为要注入的Bean名称。

Using @Value

Spring提供了一个默认的宽松内嵌值解析器。 它将尝试解析属性值,如果无法解析,则将属性名称(例如$ {catalog.name})作为值注入。

如果要严格控制不存在的值,则应声明一个PropertySourcesPlaceholderConfigurer bean

如果无法解析任何$ {}占位符,则使用上述配置可确保Spring初始化失败。 也可以使用setPlaceholderPrefix,setPlaceholderSuffix或setValueSeparator之类的方法来自定义占位符。

当使用JavaConfig配置PropertySourcesPlaceholderConfigurer时,@Bean方法必须是静态的。

Spring Boot默认配置一个PropertySourcesPlaceholderConfigurer bean,它将从application.properties和application.yml文件获取属性。

Spring BeanPostProcessor使用ConversionService来处理将@Value中的String值转换为目标类型的过程。 如果要为自己的自定义类型提供转换支持,则可以提供自己的ConversionService bean实例

相关类:

@see org.springframework.core.convert.ConversionService

@see org.springframework.context.support.PropertySourcesPlaceholderConfigurer

Using @PostConstruct and @PreDestroy (JSR-250)

The CommonAnnotationBeanPostProcessor not only recognizes the @Resource annotation but also the JSR-250 lifecycle annotations: javax.annotation.PostConstruct and javax.annotation.PreDestroy.

🌟Classpath Scanning and Managed Components

🔑关键词: @Component ;Stereotype Annotations; @ComponentScan; spring-context-indexer

从Spring 3.0开始,Spring JavaConfig项目提供的许多功能是核心Spring Framework的一部分。这使您可以使用Java而不是使用传统的XML文件来定义bean。请看一下@ Configuration,@ Bean,@ Import和@DependsOn注释,以获取有关如何使用这些新功能的示例。

@Component and Further Stereotype Annotations (模式注解)

从Spring 3.0开始,Spring JavaConfig项目提供的许多功能是核心Spring Framework的一部分。这使您可以使用Java而不是使用传统的XML文件来定义bean。请看一下@ Configuration,@ Bean,@ Import和@DependsOn注释,以获取有关如何使用这些新功能的示例。

@Repository批注是实现存储库的角色或构造型(也称为数据访问对象或DAO)的任何类的标记。该标记的用途包括自动翻译异常,如“异常翻译”中所述。

Spring提供了进一步的构造型注释:@ Component,@ Service和@Controller。 @Component是任何Spring托管组件的通用构造型。 @ Repository,@ Service和@Controller是@Component的特化,用于更特定的用例(分别在持久层,服务层和表示层中)。

因此,您可以使用@Component来注释组件类,但是通过使用@ Repository,@ Service或@Controller来注释组件类,您的类更适合通过工具进行处理或与方面相关联。例如,这些构造型注释成为切入点的理想目标。 @ Repository,@ Service和@Controller在Spring框架的将来版本中也可以带有其他语义。

因此,如果在服务层使用@Component或@Service之间进行选择,则@Service显然是更好的选择。同样,如前所述,@ Repository已被支持作为持久层中自动异常转换的标记。

Using Meta-annotations and Composed Annotations(元注解)

Spring提供的许多注释都可以在您自己的代码中用作元注释。 元注释是可以应用于另一个注释的注释。 例如,前面提到的@Service注释使用@Component进行元注释。

Automatically Detecting Classes and Registering Bean Definitions(自动检测类并注册Bean定义)

要自动检测这些类并注册相应的bean,您需要将@ComponentScan添加到@Configuration类中,其中basePackages属性是这两个类的公共父包。 (或者,您可以指定一个逗号分隔,分号分隔或空格分隔的列表,其中包括每个类的父包。)

The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the <context:annotation-config> element when using <context:component-scan>.

Using Filters to Customize Scanning

Add them as includeFilters or excludeFilters attributes of the @ComponentScan annotation (or as or child elements of the `` element in XML configuration). Each filter element requires the type and expression attributes.

Filter Type

  • annotation (default)

  • assignable

  • aspectj

  • regex

  • custom

Defining Bean Metadata within Components(在组件中定义Bean元数据)

您可以将@Bean方法声明为静态方法,从而允许在不将其包含配置类创建为实例的情况下调用它们。在定义后处理器Bean(例如BeanFactoryPostProcessor或BeanPostProcessor类型)时,这特别有意义,因为此类Bean在容器生命周期的早期进行了初始化,并且应避免在那时触发配置的其他部分。

由于技术限制,对静态@Bean方法的调用永远不会被容器拦截,即使在@Configuration类中也是如此(如本节前面所述),由于技术限制:CGLIB子类只能覆盖非静态方法。结果,直接调用另一个@Bean方法具有标准的Java语义,从而导致直接从工厂方法本身直接返回一个独立的实例。

@Bean方法的Java语言可见性不会对Spring容器中的最终bean definition 产生直接影响。您可以在非@Configuration类中自由声明自己的工厂方法,也可以在任何地方声明静态方法。但是,@ Configuration类中的常规@Bean方法必须是可重写的—即,不得将它们声明为private或final。

Naming Autodetected Components(命名自动检测的组件)

当在扫描过程中自动检测到组件时,其bean名称由该scanne已知的BeanNameGenerator策略生成。

如果您不想依赖默认的Bean命名策略,则可以提供自定义Bean命名策略。 首先,实现BeanNameGenerator 接口,并确保包含默认的无参数构造函数。

Providing a Scope for Autodetected Components(提供自动检测组件的作用域)

要提供用于范围解析的自定义策略,而不是依赖于基于注释的方法,可以实现ScopeMetadataResolver接口。
确保包括默认的无参数构造函数。

Providing Qualifier Metadata with Annotations

Generating an Index of Candidate Components(生成候选组件的索引)

While classpath scanning is very fast, it is possible to improve the startup performance of large applications by creating a static list of candidates at compilation time. In this mode, all modules that are target of component scan must use this mechanism.

加快扫描速度

🌟Using JSR 330 Standard Annotations

🔑关键词: javax.inject ; @Inject; @Named

Dependency Injection with @Inject and @Named

If you would like to use a qualified name for the dependency that should be injected, you should use the @Named annotation

如果您想对注入的依赖项使用限定名称,则应使用@Named注解

@Named and @ManagedBean: Standard Equivalents to the @Component Annotation(@Component注解的比较)

与@Component相反,JSR-330 @Named和JSR-250 ManagedBean注释是不可组合的。

您应该使用Spring的原型模型来构建自定义组件注释。

Limitations of JSR-330 Standard Annotations

Spring javax.inject.* javax.inject restrictions / comments
@Autowired @Inject @Inject has no ‘required’ attribute. Can be used with Java 8’s Optional instead.
@Component @Named / @ManagedBean JSR-330 does not provide a composable model, only a way to identify named components.
@Scope(“singleton”) @Singleton The JSR-330 default scope is like Spring’s prototype. However, in order to keep it consistent with Spring’s general defaults, a JSR-330 bean declared in the Spring container is a singleton by default. In order to use a scope other than singleton, you should use Spring’s @Scope annotation. javax.inject also provides a @Scope annotation. Nevertheless, this one is only intended to be used for creating your own annotations.
@Qualifier @Qualifier / @Named javax.inject.Qualifier is just a meta-annotation for building custom qualifiers. Concrete String qualifiers (like Spring’s @Qualifier with a value) can be associated through javax.inject.Named.
@Value - no equivalent
@Required - no equivalent
@Lazy - no equivalent
ObjectFactory Provider javax.inject.Provider is a direct alternative to Spring’s ObjectFactory, only with a shorter get() method name. It can also be used in combination with Spring’s @Autowired or with non-annotated constructors and setter methods.

🌟Java-based Container Configuration(基于Java的容器配置)

🔑关键词: @Bean; @Configuration;AnnotationConfigApplicationContext;lite vs full;@Import; @ImportResource;@Condition

This section covers how to use annotations in your Java code to configure the Spring container. It includes the following topics:

Basic Concepts: @Bean and @Configuration

@Configuration: 用@Configuration注释类表示该类的主要目的是作为Bean定义的来源。 此外,@Configuration类允许通过调用同一类中的其他@Bean方法 来定义Bean间的依赖关系。

@Bean : Indicates that a method produces a bean to be managed by the Spring container.

Full @Configuration vs “lite” @Bean mode?

lite @Bean mode模式下, @Bean方法不会被CGLIB代理 ,所以尽量使用Full @Configuration模式

Instantiating the Spring Container by Using AnnotationConfigApplicationContext

这种通用的ApplicationContext实现不仅能够接受@Configuration类作为输入,

而且还可以接受普通的@Component类和带有JSR-330元数据注释的类。

scan & register

package org.springframework.context.annotation;

/**
 * Common interface for annotation config application contexts,
 * defining {@link #register} and {@link #scan} methods.
 *
 * @author Juergen Hoeller
 * @since 4.1
 */
public interface AnnotationConfigRegistry {

   /**
    * Register one or more annotated classes to be processed.
    * <p>Calls to {@code register} are idempotent; adding the same
    * annotated class more than once has no additional effect.
    * @param annotatedClasses one or more annotated classes,
    * e.g. {@link Configuration @Configuration} classes
    */
   void register(Class<?>... annotatedClasses);

   /**
    * Perform a scan within the specified base packages.
    * @param basePackages the packages to check for annotated classes
    */
   void scan(String... basePackages);

}

more details: @see org.springframework.context.annotation.AnnotationConfigApplicationContext

Support for Web Applications with AnnotationConfigWebApplicationContext

Using the @Bean Annotation

  • Declaring a Bean
  • Bean Dependencies
  • Receiving Lifecycle Callbacks
  • Specifying Bean Scope
  • Customizing Bean Naming
  • Bean Aliasing
  • Bean Description

@see org.springframework.context.annotation.Bean

Using the @Configuration annotation

Injecting Inter-bean Dependencies(注入bean间的依赖关系)

Lookup Method Injection

Further Information About How Java-based Configuration Works Internally

Composing Java-based Configurations

Using the @Import Annotation

从Spring Framework 4.2开始,@ Import还支持对常规组件类的引用,类似于AnnotationConfigApplicationContext.register方法。

如果要通过使用一些配置类作为入口点来显式定义所有组件,从而避免组件扫描,则此功能特别有用。

Conditionally Include @Configuration Classes or @Bean Methods

The @Profile annotation is actually implemented by using a much more flexible annotation called @Conditional.

The @Conditional annotation indicates specific org.springframework.context.annotation.Condition implementations that should be consulted before a @Bean is registered.

@Profile

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {

    /**
     * The set of profiles for which the annotated component should be registered.
     */
    String[] value();

}

ProfileCondition

class ProfileCondition implements Condition {
  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
    if (attrs != null) {
      for (Object value : attrs.get("value")) {
        if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {
          return true;
        }
      }
      return false;
    }
    return true;
  }
}

Condition

@FunctionalInterface
public interface Condition {

   /**
    * Determine if the condition matches.
    * @param context the condition context
    * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
    * or {@link org.springframework.core.type.MethodMetadata method} being checked
    * @return {@code true} if the condition matches and the component can be registered,
    * or {@code false} to veto the annotated component's registration
    */
   boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

Combining Java and XML Configuration

Spring’s @Configuration class support does not aim to be a 100% complete replacement for Spring XML.

XML-centric Use of @Configuration Classes

Declaring @Configuration classes as plain Spring <bean/ > elements

<!-- enable processing of annotations such as @Autowired and @Configuration -->
<context:annotation-config/>
<bean class="com.acme.AppConfig"/>

<context:annotation-config /> 仅能够在已经在已经注册过的bean上面起作用,所以需要手动注册

Using <context:component-scan/ > to pick up @Configuration classes**

<!-- picks up and registers AppConfig as a bean definition -->
 <context:component-scan base-package="com.acme"/>

@ConfigurationClass-centric Use of XML with@ImportResource

@ImportResource

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ImportResource {

    /**
     * Alias for {@link #locations}.
     * @see #locations
     * @see #reader
     */
    @AliasFor("locations")
    String[] value() default {};

    /**
     * Resource locations from which to import.
     * <p>Supports resource-loading prefixes such as {@code classpath:},
     * {@code file:}, etc.
     * <p>Consult the Javadoc for {@link #reader} for details on how resources
     * will be processed.
     * @since 4.2
     * @see #value
     * @see #reader
     */
    @AliasFor("value")
    String[] locations() default {};

    /**
     * {@link BeanDefinitionReader} implementation to use when processing
     * resources specified via the {@link #value} attribute.
     * <p>By default, the reader will be adapted to the resource path specified:
     * {@code ".groovy"} files will be processed with a
     * {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader GroovyBeanDefinitionReader};
     * whereas, all other resources will be processed with an
     * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader XmlBeanDefinitionReader}.
     * @see #value
     */
    Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;

}

🌟Environment Abstraction (环境抽象)

🔑关键词: Environment; profiles; properties;PropertySources;PropertySourcesPlaceholderConfigurer

The Environment interface is an abstraction integrated in the container that models two key aspects of the application environment: profiles and properties.

Environment接口是集成在容器中的抽象,它对应用程序环境的两个关键方面进行建模:profiles和properties

A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active. Beans may be assigned to a profile whether defined in XML or with annotations.

The role of the Environment object with relation to profiles is in determining which profiles (if any) are currently active, and which profiles (if any) should be active by default.

Properties play an important role in almost all applications and may originate from a variety of sources: properties files, JVM system properties, system environment variables, JNDI, servlet context parameters, ad-hoc Properties objects, Map objects, and so on.

The role of the Environment object with relation to properties is to provide the user with a convenient service interface for configuring property sources and resolving properties from them.

Bean Definition Profiles

Using @Profile

XML Bean Definition Profiles

Activating a Profile

spring.profiles.active

Default Profile

default

PropertySource Abstraction

For a common StandardServletEnvironment, the full hierarchy is as follows, with the highest-precedence entries at the top:

  • ServletConfig parameters (if applicable — for example, in case of a DispatcherServlet context)
  • ServletContext parameters (web.xml context-param entries)
  • JNDI environment variables (java:comp/env/ entries)
  • JVM system properties (-D command-line arguments)
  • JVM system environment (operating system environment variables)
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();

Using @PropertySource

The @PropertySource annotation provides a convenient and declarative mechanism for adding a PropertySource to Spring’s Environment.

Placeholder Resolution in Statements

Historically, the value of placeholders in elements could be resolved only against JVM system properties or environment variables. This is no longer the case.

Because the Environment abstraction is integrated throughout the container, it is easy to route resolution of placeholders through it.

This means that you may configure the resolution process in any way you like.

You can change the precedence of searching through system properties and environment variables or remove them entirely.

@See org.springframework.context.support.PropertySourcesPlaceholderConfigurer

🌟Registering a LoadTimeWeaver

weaving(编织 编译时、加载时、运行时) 这里是类加载时

The LoadTimeWeaver is used by Spring to dynamically transform classes as they are loaded into the Java virtual machine (JVM).

@See https://www.cnblogs.com/wade-luffy/p/6073702.html

🌟Additional Capabilities of the ApplicationContext (BeanFactory的扩展)

🔑关键词:BeanFactory;ResourceLoader;MessageSource;ResourceBundleMessageSource;Environment;EventPublisher;

@EventListener;ContextLoaderListener;

image-20191120093906082

To enhance BeanFactory functionality in a more framework-oriented style, the context package also provides the following functionality:

  • Access to messages in i18n-style, through the MessageSource interface.
  • Access to resources, such as URLs and files, through the ResourceLoader interface.
  • Event publication, namely to beans that implement the ApplicationListener interface, through the use of the ApplicationEventPublisher interface.
  • Loading of multiple (hierarchical) contexts, letting each be focused on one particular layer, such as the web layer of an application, through the HierarchicalBeanFactory interface.

Internationalization using MessageSource

Standard and Custom Events

Event Explanation
ContextRefreshedEvent Published when the ApplicationContext is initialized or refreshed (for example, by using the refresh() method on the ConfigurableApplicationContext interface). Here, “initialized” means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use. As long as the context has not been closed, a refresh can be triggered multiple times, provided that the chosen ApplicationContext actually supports such “hot” refreshes. For example, XmlWebApplicationContext supports hot refreshes, but GenericApplicationContext does not.
ContextStartedEvent Published when the ApplicationContext is started by using the start() method on the ConfigurableApplicationContext interface. Here, “started” means that all Lifecycle beans receive an explicit start signal. Typically, this signal is used to restart beans after an explicit stop, but it may also be used to start components that have not been configured for autostart (for example, components that have not already started on initialization).
ContextStoppedEvent Published when the ApplicationContext is stopped by using the stop() method on the ConfigurableApplicationContext interface. Here, “stopped” means that all Lifecycle beans receive an explicit stop signal. A stopped context may be restarted through a start() call.
ContextClosedEvent Published when the ApplicationContext is being closed by using the close() method on the ConfigurableApplicationContext interface or via a JVM shutdown hook. Here, “closed” means that all singleton beans will be destroyed. Once the context is closed, it reaches its end of life and cannot be refreshed or restarted.
RequestHandledEvent A web-specific event telling all beans that an HTTP request has been serviced. This event is published after the request is complete. This event is only applicable to web applications that use Spring’s DispatcherServlet.
ServletRequestHandledEvent A subclass of RequestHandledEvent that adds Servlet-specific context information.

Annotation-based Event Listeners

As of Spring 4.2, the event infrastructure has been significantly improved and offers an annotation-based model as well as the ability to publish any arbitrary event (that is, an object that does not necessarily extend from ApplicationEvent). When such an object is published, we wrap it in an event for you.

Asynchronous Listeners

Be aware of the following limitations when using asynchronous events:

  • If an asynchronous event listener throws an Exception, it is not propagated to the caller. See AsyncUncaughtExceptionHandler for more details.
  • Asynchronous event listener methods cannot publish a subsequent event by returning a value. If you need to publish another event as the result of the processing, inject an ApplicationEventPublisher to publish the event manually.

Ordering Listeners

@Order

Generic Events

@see org.springframework.core.ResolvableTypeProvider

Convenient Access to Low-level Resources

An application context is a ResourceLoader, which can be used to load Resource objects. A Resource is essentially a more feature rich version of the JDK java.net.URL class

Convenient ApplicationContext Instantiation for Web Applications

You can register an ApplicationContext by using the ContextLoaderListener

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Deploying a Spring ApplicationContext as a Java EE RAR File

Such RAR deployment units are usually self-contained. They do not expose components to the outside world, not even to other modules of the same application.

🌟The BeanFactory

🔑关键词: DefaultListableBeanFactory ; extensions

Note that the core BeanFactory API level and its DefaultListableBeanFactory implementation do not make assumptions about the configuration format or any component annotations to be used. All of these flavors come in through extensions (such as XmlBeanDefinitionReader and AutowiredAnnotationBeanPostProcessor) and operate on shared BeanDefinition objects as a core metadata representation.

This is the essence of what makes Spring’s container so flexible and extensible.

BeanFactory or ApplicationContext?

For many extended container features, such as annotation processing and AOP proxying, the BeanPostProcessor extension point is essential.

If you use only a plain DefaultListableBeanFactory, such post-processors do not get detected and activated by default. This situation could be confusing, because nothing is actually wrong with your bean configuration.

Rather, in such a scenario, the container needs to be fully bootstrapped through additional setup.

The following table lists features provided by the BeanFactory and ApplicationContext interfaces and implementations.

Feature BeanFactory ApplicationContext
Bean instantiation/wiring Yes Yes
Integrated lifecycle management No Yes
Automatic BeanPostProcessor registration No Yes
Automatic BeanFactoryPostProcessor registration No Yes
Convenient MessageSource access (for internalization) No Yes
Built-in ApplicationEvent publication mechanism No Yes

总览

顶级接口

  • BeanFactory
    • bean (beanDefined);
    • 状态(作用域)/行为(回调,bean extends)/关系(依赖)
    • contains extension (BPF/BBPF/FactoryBean)
  • ApplicationContext
    • Messagesource
    • Event
    • layer (AOP /web /auto registration )

Core (core/asm/cglib/util)

  • Env
  • IO
  • Type : Core support package for type introspection.(内省)
  • @AliasFor / @Order

Annotaion(2.5 / 3.0/ 4.0/ 5.0)


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com

文章标题:Documentation-Spring_Core_IOC

字数:11.6k

本文作者:zhengyumin

发布时间:2019-10-29, 21:51:07

最后更新:2019-12-22, 17:31:36

原始链接:http://zyumin.github.io/2019/10/29/Documentation-Spring-Core-IOC/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。