@bean annotation details
Bean usage
The @bean representation produces a Spring-managed Bean with the same property name semantics as configured for the tag in Spring XML
public MyBean myBean(a) {
// instantiate and configure MyBean obj
return obj;
}
Copy the code
When using the name attribute is available, the default strategy for determining the bean name is to use the name of the method. This is convenient and intuitive, but if you want explicit naming, you can use the name attribute (or its alias {value}) on the annotation.
Also note that name takes an array of strings, allowing multiple names (that is, the primary bean name with one or more aliases) for a single bean.
@Bean({"b1", "b2"}) // bean available as 'b1' and 'b2', but not 'myBean'
public MyBean myBean(a) {
// instantiate and configure MyBean obj
return obj;
}
Copy the code
Bean is enhanced
The @bean annotation does not provide Profile, Scope, Lazy, DependsOn, Primary, Order functions
Profile, Scope, Lazy, DependsOn, Primary, and Order attributes are configured on the bean instead of attributes
@Bean
@Profile("production")
@Scope("prototype")
@Order(-100)
public MyBean myBean(a) {
// instantiate and configure MyBean obj
return obj;
}
Copy the code
The semantics of the above annotations match their use at the component class level:
- @profile allows you to optionally include certain beans.
- @scope changes the Scope of the bean from a singleton to a specified Scope.
- The @lazy effect is only practical if the default singleton scope is used.
- @dependson forces the creation of a specific other bean before this bean is created, along with any dependencies that the bean represents by direct reference, which is often helpful for singleton initiation.
- @primary is a mechanism to resolve ambiguity at the injection point level if you need to inject a single target component, but multiple beans match by type
-
- @ the Order; The @Bean method can also declare qualifier annotations and @Order, and annotations on the corresponding component class are considered as appropriate during injection point parsing, but each Bean definition can be very individual (in the case of multiple definitions of the same Bean class). After the initial type match, the value of Order Narrows the candidate set; The order value determines the sequential injection point at which elements are parsed in the collection case (matching multiple target beans by type and qualifier).
- @ the Order value may influence the Priority of the injection point, but please note that they will not affect the singleton startup sequence, this is a dependency and @ DependsOn statement, in addition, the javax.mail. The annotation. The Priority at this level is not available, because it can’t on the method statement. Its semantics can be used with the @order value in combination with the @primary value to tune individual beans of each type.
@bean usage scenarios
Normally, the @bean method is declared in the @Configuration class. Therefore, the @Configuration class and its factory methods cannot be marked as final or private in this mode. In this case, bean methods can be called directly to reference other @Bean methods in the same class. This ensures that references between beans are strongly typed and conductable. Such inter-bean references are guaranteed to enforce scoping and AOP semantics as well as getBean() lookups. These semantics, known from the original “Spring JavaConfig” project, require that CGLIB subclasses of each such configuration class be subclassed at run time.
@Configuration
public class AppConfig {
@Bean
public FooService fooService(a) {
return new FooService(fooRepository());
}
@Bean
public FooRepository fooRepository(a) {
return new JdbcFooRepository(dataSource());
}
// ...
}
Copy the code
Note:
- @bean methods can also be declared in classes annotated with @Configuration. For example, you can declare a bean method in the @Component class or even in other classes as. In this case, the @Bean method is handled in so-called Lite mode.
- The Bean container treats bean methods in Lite mode as normal factory methods (similar to the factory-method declaration in XML), applying scope and lifecycle callbacks as appropriate. In this case, the included class remains the same, and there are no exception constraints on the containing class or factory method.
- Contrary to the semantics of the bean methods in the @Configuration class, inter-bean references are not supported in Lite mode. In contrast, when an @Bean method calls another @Bean method in Lite mode, the call is a standard Java method call; Spring does not intercept calls through the CGLIB proxy. This is similar to the internal @Transactional method call, however in proxy mode Spring does not intercept the call; But only in AspectJ mode, Spring intercepts the call. The following
@Component
public class Calculator {
public int sum(int a, int b) {
return a+b;
}
@Bean
public MyBean myBean(a) {
return newMyBean(); }}Copy the code
@Bean with BeanFactoryPostProcessor (BFPP)
For the return Spring org. Springframework. Beans. Factory. Config. Spring BeanFactoryPostProcessor. Spring BeanFactoryPostProcessor () type @ Bean method, Special care must be taken. Because BFPP objects must be instantiated early in the container life cycle, they can interfere with the processing of internal @Autowired, @Value, and @postconstruct annotations. @ the Configuration class. To avoid these lifecycle issues, mark the @bean method returned by BFPP- as static. Such as:
@Bean
public static PropertySourcesPlaceholderConfigurer pspc(a) {
// instantiate, configure and return pspc ...
}
Copy the code
Spring BeanFactoryPostProcessor. By the method marked as static, can cause the statement in not @ Configuration class instances of the situation by using this method, so as to avoid the conflict of the life cycle. Note, however, that the @bean method under Static is not enhanced for scoping and AOP semantics, as described above. This works in the BFPP case because other @bean methods do not normally reference them and will issue WARN level log messages for any non-static @bean methods that have a return type that can be assigned to BeanFactoryPostProcessor
@ the Bean’s method
- value()
/**
* Alias for {@link #name}.
* <p>Intended to be used when no other attributes are needed, for example:
* {@code @Bean("customBeanName")}.
* @since 4.3.3
* @see #name
*/
@AliasFor("name")
String[] value() default {};
Copy the code
- name()
The name of the Bean, or alias the main Bean name if there are more than one. If not specified, the Bean name is the name of the annotated method. If the method name is specified, it is ignored. If no other properties are declared, the bean name and alias can also be configured through the value property
/**
* The name of this bean, or if several names, a primary bean name plus aliases.
* <p>If left unspecified, the name of the bean is the name of the annotated method.
* If specified, the method name is ignored.
* <p>The bean name and aliases may also be configured via the {@link #value}
* attribute if no other attributes are declared.
* @see #value
*/
@AliasFor("value")
String[] name() default {};
Copy the code
- autowire()
Are dependencies injected by name or type through convention based autowiring? Note that this autowiring pattern is only externally driven autowiring based on convention based bean property setter methods, similar to XML bean definitions. The default mode does allow annotation-driven autowiring. “No” refers only to externally driven autowiring and does not affect any autowiring requirements expressed by the bean class itself through annotations. Spring5.1 deprecated because @bean factory method parameter parsing and @autowired processing replaced name/type-based Bean property injection
/**
* Are dependencies to be injected via convention-based autowiring by name or type?
* <p>Note that this autowire mode is just about externally driven autowiring based
* on bean property setter methods by convention, analogous to XML bean definitions.
* <p>The default mode does allow for annotation-driven autowiring. "no" refers to
* externally driven autowiring only, not affecting any autowiring demands that the
* bean class itself expresses through annotations.
* @see Autowire#BY_NAME
* @see Autowire#BY_TYPE
* @deprecatedAs of 5.1, since {@code @Bean} factory method argument resolution and
* {@code @Autowired} processing supersede name/type-based bean property injection
*/
@Deprecated
Autowire autowire(a) default Autowire.NO;
Copy the code
- autowireCandidate()
Is this bean suitable for automatic wiring to other beans? The default is true; For internal proxies, set it to false rather than having the same type of Bean appear elsewhere.
/**
* Is this bean a candidate for getting autowired into some other bean?
* <p>Default is {@code true}; set this to {@code false} for internal delegates
* that are not meant to get in the way of beans of the same type in other places.
* @since5.1 * /
boolean autowireCandidate(a) default true;
Copy the code
-
initMethod()
The optional name of the method to be invoked on the Bean instance during initialization. Not commonly used because the method can be called programmatically directly within the body of the Bean annotation method. The default value is “” (an empty string), indicating that there is no initialization method to call.
/**
* The optional name of a method to call on the bean instance during initialization.
* Not commonly used, given that the method may be called programmatically directly
* within the body of a Bean-annotated method.
* <p>The default value is {@code ""}, indicating no init method to be called.
* @see org.springframework.beans.factory.InitializingBean
* @seeOrg. Springframework. Context. ConfigurableApplicationContext# refresh () * initialization time to call the method on the Bean instance name optional. * Not commonly used since the method can be called programmatically directly within the body of the Bean annotation method. * The default value is "" (empty string), indicating that there is no initialization method to call. * /
String initMethod(a) default "";
Copy the code
-
destroyMethod
The optional name of the method to be called on the Bean instance when the application context is closed, such as the close () method on the JDBC DataSource implementation or the Hibernate SessionFactory object. The method must have no arguments, but can throw any exception. For the user’s convenience, the container will try to infer a destroy method on the object returned by the @Bean method. For example, given an @Bean method that returns a BasicDataSource of Apache Commons DBCP, the container will notice that the close () method is available on that object and automatically register it as destroyMethod. Currently, this “destruction method inference” is limited to detecting public no-argument methods named “close” or “shutdown.” This method can be declared at any level of the inheritance hierarchy, and will be detected regardless of the return type of the @Bean method (that is, detection occurs reflexively against the Bean instance itself at creation time). To disable destroy method inference for a particular @bean, specify an empty string as a value, such as @bean (destroyMethod = “”). Note that org. Springframework. Beans. Factory. DisposableBean callback interface will be detected, and call the corresponding destroy methods: In other words, code destroyMethod = “” affects only custom close/close methods, whereas java.io.Closeable/ java.lang.AutoCloseable declares the close method. Note: Only called on beans whose life cycle is under full control of the factory, always for singletons, but not guaranteed for any other scope.
/**
* The optional name of a method to call on the bean instance upon closing the
* application context, for example a {@code close()} method on a JDBC
* {@code DataSource} implementation, or a Hibernate {@code SessionFactory} object.
* The method must have no arguments but may throw any exception.
* <p>As a convenience to the user, the container will attempt to infer a destroy
* method against an object returned from the {@code @Bean} method. For example, given
* an {@code @Bean} method returning an Apache Commons DBCP {@code BasicDataSource},
* the container will notice the {@code close()} method available on that object and
* automatically register it as the {@codedestroyMethod}. This 'destroy method * inference' is currently limited to detecting only public, no-arg methods named * 'close' or 'shutdown'. The method may be declared at any level of the inheritance * hierarchy and will be detected regardless of the return type of the {@code @Bean}
* method (i.e., detection occurs reflectively against the bean instance itself at
* creation time).
* <p>To disable destroy method inference for a particular {@code @Bean}, specify an
* empty string as the value, e.g. {@code @Bean(destroyMethod="")}. Note that the
* {@link org.springframework.beans.factory.DisposableBean} callback interface will
* nevertheless get detected and the corresponding destroy method invoked: In other
* words, {@code destroyMethod=""} only affects custom close/shutdown methods and
* {@link java.io.Closeable}/{@link java.lang.AutoCloseable} declared close methods.
* <p>Note: Only invoked on beans whose lifecycle is under the full control of the
* factory, which is always the case for singletons but not guaranteed for any
* other scope.
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
String destroyMethod(a) default AbstractBeanDefinition.INFER_METHOD;
Copy the code