Spring supports the following three annotations for Bean definition based on Annotations:
@ Component annotation and extension @ Repository, @ Service, and @ Controller provided by Spring, as shown in 12-1;
The @ ManagedBean annotation defined in JSR-250 1.1 is one of the Java EE 6 standard specifications and is not included in JDK and needs to be used in the application server environment (such as Jboss), as shown in 12-2;
The @ Named annotation of the JSR-330, as shown in 12-3.
Figure 12-1 annotation and extension of @ Component included in Spring
Figure 12-2 @ ManagedBean annotation and custom extension defined in the JSR-250
Figure 12-3 JSR-330 @ Named annotation and custom Extension
The custom extensions in Figure 12-2 and Figure 12-3 are used in combination with Spring's built-in pattern annotation to expand the customization, and are not included in the Java EE 6 specification, in Java EE 6, the corresponding service layer and DAO layer functions are implemented by ejbs.
In Java EE, some annotations are run in multiple places. For example, @ Named can be placed in the type, field, and method parameter fields. Therefore, it is generally placed in the type to indicate the definition, it is generally used (such as dependency injection) when placed on parameters and methods ).
1. annotation and extension of @ Component included in Spring
I. @ Component: defines Spring management Bean. The usage is as follows:
Java code: Java code @ Component ("identifier ")
POJO class
Using the @ Component Annotation on the class indicates that it becomes a Component. If the identifier is not written, it is the class name by default. It is recommended that you write a name by yourself.
Define the test Bean class:
Java code: Java code package cn. S. spring. chapter12;
Import org. springframework. beans. factory. annotation. Autowired;
Import org. springframework. context. ApplicationContext;
Import org. springframework. stereotype. Component;
@ Component ("component ")
Public class TestCompoment {
@ Autowired
Private ApplicationContext ctx;
Public ApplicationContext getCtx (){
Return ctx;
}
}
Define test classes and test methods:
Java code: Java code package cn. S. spring. chapter12;
// Omit import
Public class ComponentDefinitionWithAnnotationTest {
Private static String configLocation = "classpath: chapter12/componentDefinitionWithAnnotation. xml ";
Private static ApplicationContext ctx = new ClassPathXmlApplicationContext (configLocation );
@ Test
Public void testComponent (){
TestCompoment component = ctx. getBean ("component", TestCompoment. class );
Assert. assertNotNull (component. getCtx ());
}
}
If the test succeeds, the POJO class annotated by @ Component will be automatically recognized by Spring and registered to the Spring container. The POJO class automatically supports automatic assembly.
@ AspectJ style Aspect can be identified by @ Compenent annotation as Spring management Bean, while @ Aspect annotation cannot be automatically recognized and registered as Bean by Spring, which must be completed by @ Component annotation, example:
Java code: Java code package cn. ipvs. spring. chapter12.aop;
// Omit import
@ Component
@ Aspect
Public class TestAspect {
@ Pointcut (value = "execution (**(..))")
Private void pointcut (){}
@ Before (value = "pointcut ()")
Public void before (){
System. out. println ("======= before ");
}
}
Define the Section as Spring Bean management by @ Component.
2. @ Repository: @ Component extension. The POJO class annotated by @ Repository indicates the implementation of the DAO layer. As a result, the implementation of the DAO layer occurs when the annotation is seen. The usage is the same as that of @ Component;
1. Define the test Bean class:
Java code: Java code package cn. ipvs. spring. chapter12.dao. hibernate;
Import org. springframework. stereotype. Repository;
@ Repository ("testHibernateDao ")
Public class TestHibernateDaoImpl {
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testDao (){
TestHibernateDaoImpl dao =
Ctx. getBean ("testHibernateDao", TestHibernateDaoImpl. class );
Assert. assertNotNull (dao );
}
If the test succeeds, the POJO class annotated by @ Repository is automatically recognized by Spring and registered to the Spring container. The POJO class automatically supports automatic assembly and is represented by the class annotated by @ Repository to implement the DAO layer.
3. @ Service: @ Component extension. The POJO class annotated by @ Service indicates the implementation of the Service layer. As a result, the implementation of the Service layer is considered as the annotation. The usage is the same as that of @ Component;
1. Define the test Bean class:
Java code: Java code package cn. ipvs. spring. chapter12.service. impl;
Import org. springframework. beans. factory. annotation. Autowired;
Import org. springframework. beans. factory. annotation. Qualifier;
Import org. springframework. stereotype. Service;
Import cn. ipvs. spring. chapter12.dao. hibernate. TestHibernateDaoImpl;
@ Service ("testService ")
Public class TestServiceImpl {
@ Autowired
@ Qualifier ("testHibernateDao ")
Private TestHibernateDaoImpl dao;
Public TestHibernateDaoImpl getDao (){
Return dao;
}
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testService (){
TestServiceImpl service = ctx. getBean ("testService", TestServiceImpl. class );
Assert. assertNotNull (service. getDao ());
}
If the test succeeds, the POJO class annotated by @ Service is automatically recognized by Spring and registered to the Spring container. The POJO class automatically supports automatic assembly, and the class annotated by @ Service indicates the implementation of the Service layer.
4. @ Controller: @ Component extension. The class annotated by @ Controller represents the implementation of the Web layer. When you see this annotation, you will think of the implementation of the Web layer. The usage is the same as that of @ Component;
1. Define the test Bean class:
Java code: Java code package cn. S. spring. chapter12.action;
// Omit import
@ Controller
Public class TestAction {
@ Autowired
Private TestServiceImpl testService;
Public void list (){
// Call the business logic layer method
}
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testWeb (){
TestAction action = ctx. getBean ("testAction", TestAction. class );
Assert. assertNotNull (action );
}
If the test succeeds, the classes annotated by @ Controller are automatically recognized by Spring and registered to the Spring container. The classes annotated by @ Controller automatically support automatic assembly and are represented by the Web layer.
Have you noticed that @ Controller does not define Bean identifiers? The default Bean name will start with a lower-case class name (excluding the package name ), that is, the Bean identifier of the "TestAction" class is "testAction ".
6. Custom extensions: Spring has three built-in general extension Annotations: @ Repository, @ Service, and @ Controller. In most cases, you do not need to define your own extensions, here we will demonstrate how to extend the @ Component annotation to meet the needs of some special protocols;
Here we may need a Cache layer to define the Cache Bean, so we need to customize a @ Cache annotation to represent the Cache class.
1. Extension @ Component:
Java code: Java code package cn. S. spring. chapter12.stereotype;
// Omit import
@ Target ({ElementType. TYPE })
@ Retention (RetentionPolicy. RUNTIME)
@ Brief ented
@ Component
Public @ interface Cache {
String value () default "";
}
The extension is very simple. You only need to annotate @ Component on the extension annotation. @ Repository, @ Service, and @ Controller are also implemented in this way. Nothing special
2. Define the test Bean class:
Java code: Java code package cn. ipvs. spring. chapter12.cache;
@ Cache ("cache ")
Public class TestCache {
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testCache (){
TestCache cache = ctx. getBean ("cache", TestCache. class );
Assert. assertNotNull (cache );
}
If the test succeeds, it means that the custom @ Cache annotation can work well and achieve our goal. @ Cache is used to indicate that the class to be annotated is the Cache layer Bean.
@ ManagedBean annotation defined in 12.3.3 JSR-250
@ Javax. annotation. managedBean must be used on the application server that implements Java EE 6 specifications. Although Spring3 is implemented, @ javax. annotation. managedBean is defined only in the Java EE 6 environment. Therefore, we need to define the ManagedBean class before testing.
1. Define the javax. annotation. ManagedBean annotation class:
Java code: Java code package javax. annotation;
Import java. lang. annotation. ElementType;
Import java. lang. annotation. Retention;
Import java. lang. annotation. RetentionPolicy;
Import java. lang. annotation. Target;
@ Target (ElementType. TYPE)
@ Retention (RetentionPolicy. RUNTIME)
Public @ interface ManagedBean {
String value () default "";
}
It is exactly the same as @ Component. The only difference is the name and creator (one is Spring and the other is the Java EE Specification ).
2. Define the test Bean class:
Java code: Java code package cn. S. spring. chapter12;
Import javax. annotation. Resource;
Import org. springframework. context. ApplicationContext;
@ Javax. annotation. ManagedBean ("managedBean ")
Public class TestManagedBean {
@ Resource
Private ApplicationContext ctx;
Public ApplicationContext getCtx (){
Return ctx;
}
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testManagedBean (){
TestManagedBean testManagedBean = ctx. getBean ("managedBean", TestManagedBean. class );
Assert. assertNotNull (testManagedBean. getCtx ());
}
If the test succeeds, the @ ManagedBean annotation class works normally.
Custom extensions are not introduced. You can refer to @ Component to complete the custom extensions shown in 12-2.
12.3.4 @ Named annotation of the JSR-330
@ Named can be used not only for dependency injection to specify the identifier of the injected Bean, but also for defining the Bean. That is, the annotation indicates the Bean defined in the type, and the annotation indicates the Bean identifier of the specified dependency injection on the non-type (such as field.
1. Define the test Bean class:
Java code: Java code package cn. S. spring. chapter12;
// Omit import
@ Named ("namedBean ")
Public class TestNamedBean {
@ Inject
Private ApplicationContext ctx;
Public ApplicationContext getCtx (){
Return ctx;
}
}
2. Use chapter12/componentDefinitionWithAnnotation. xml in the Spring configuration file without modification;
3. Define the Test method:
Java code: Java code @ Test
Public void testNamedBean (){
TestNamedBean testNamedBean =
Ctx. getBean ("namedBean", TestNamedBean. class );
Assert. assertNotNull (testNamedBean. getCtx ());
}
If the test succeeds, the @ Named annotation class works normally.
The custom extension is not introduced. You can refer to @ Component to complete the custom Extension Section 12-3.
12.3.5 fine-grained Bean definition Scanning
Bean definitions are completely eliminated in the XML configuration, but there is only one <context: component-scan> label to support annotation Bean definition scanning.
The examples at the front end use the default scan settings. What if we have a few components that do not want to be scanned and automatically registered and want to change the default Bean ID generation policy? Next, let's take a look at how to fine-grained Bean definition scanning. The specific definitions are as follows:
Java code: Java code <context: component-scan
Base-package = ""
Resource-pattern = "**/*. class"
Name-generator = "org. springframework. context. annotation. AnnotationBeanNameGenerator"
Use-default-filters = "true"
Annotation-config = "true">
<Context: include-filter type = "aspectj" expression = ""/>
<Context: exclude-filter type = "regex" expression = ""/>
</Context: component-scan>
Base-package: indicates the starting position of the scanning annotation class, which will be scanned in the specified package. The annotation classes in other packages will not be scanned. By default, all class paths will be scanned;
Resource-pattern: indicates the suffix matching mode of the scanning annotation class. That is, "base-package + resource-pattern" is used to match components in the class path, the default suffix is "**/*. class, that is, all. class file at the end of the class;
Name-generator: the default Bean identifier generation policy. The default policy is AnnotationBeanNameGenerator, which generates a class name (excluding the package name) Starting with lowercase ); you can customize your own identifier generation policies;
Use-default-filters: the default value "true" indicates filtering classes with @ Component, @ ManagedBean, and @ Named annotations. If it is set to "false", the default annotations are not filtered to define beans, that is, these annotation classes cannot be filtered out, that is, Bean definitions cannot be implemented through these annotations;
Annotation-config: Indicates whether to automatically support annotation to implement Bean dependency injection. It is supported by default. If it is set to false, dependency injection that supports annotation is disabled. You must use <context: enable annotation-config/>.
By default, classes with @ Component, @ ManagedBean, and @ Named annotations are automatically filtered and registered as Spring management beans: specify the custom filter in the component-scan> label to register the class that matches the filter condition as the Spring management Bean. The specific definition is as follows:
Java code: Java code <context: include-filter type = "aspectj" expression = ""/>
<Context: exclude-filter type = "regex" expression = ""/>
<Context: include-filter>: indicates that the filtered classes will be registered as Spring management beans;
<Context: exclude-filter>: indicates that the filtered class is not registered as a Spring management Bean, which has a higher priority than <context: include-filter>;
Type: indicates the filter type. Currently, the annotation type, class type, regular expression, and aspectj expression filters are supported. You can also customize your own filters to implement org. springframework. core. type. filter. typeFilter;
Expression: the filter expression.
Generally, custom filtering is not required. For more information, see the following example:
1. cn. ipvs. spring. chapter12.TestBean14 is automatically registered as a Spring management Bean:
Java code: Java code <context: include-filter type = "assignable" expression = "cn. S. spring. chapter12.TestBean14"/>
2. automatically register all annotation org. aspectj. lang. annotation. Aspect as Spring management Bean:
Java code: Java code <context: include-filter type = "annotation"
Expression = "org. aspectj. lang. annotation. Aspect"/>
3. The regular expression "cn \. S \. spring \. chapter12 \. TestBean2 *" will be excluded and not registered as a Spring management Bean:
Java code: Java code <context: exclude-filter type = "regex" expression = "cn \. S \. spring \. chapter12 \. TestBean2 *"/>
4. The matching expression "cn. S. spring. chapter12.TestBean3 *" will be excluded and will not be registered as a Spring management Bean:
Java code: Java code <context: exclude-filter type = "aspectj" expression = "cn. S. spring. chapter12.TestBean3 *"/>
The specific use depends on the needs of the project. If none of the above requirements are met, consider using a custom filter.
12.3.6 more configuration metadata
1. @ Lazy: defines the Bean to delay initialization. The usage is as follows:
Java code: Java code @ Component ("component ")
@ Lazy (true)
Public class TestCompoment {
......
}
Use the @ Lazy annotation to specify that the Bean requires delayed initialization.
2. @ DependsOn: defines the sequence of Bean initialization and destruction. The usage is as follows:
Java code: Java code @ Component ("component ")
@ DependsOn ({"managedBean "})
Public class TestCompoment {
......
}
3. @ Scope: defines the Bean Scope. The default Singleton is used as follows:
Java code: Java code @ Component ("component ")
@ Scope ("singleton ")
Public class TestCompoment {
......
}
4. @ Qualifier: Specifies the qualified descriptor, which corresponds to the <qualifier> label in XML-based configuration. The usage is as follows:
Java code: Java code @ Component ("component ")
@ Qualifier ("component ")
Public class TestCompoment {
......
}
You can use complex extensions, such as @ Mysql.
5. @ Primary: when multiple Bean candidates appear during automatic assembly, the Bean annotated as @ Primary will be the first candidate; otherwise, an exception will be thrown. The usage is as follows:
Java code: Java code @ Component ("component ")
@ Primary
Public class TestCompoment {
......
}