Spring (16) - bean definition using annotations

16 Using annotations for bean definitions

In addition to defining a bean through the bean element in the Spring configuration file. We can also use specific annotations on the Class to annotate, and then let Spring scan these specific annotations and define them as a bean.

16.1 @Component

@Component is the most basic annotation used to define beans in Spring. By marking the corresponding annotation on the Class class, Spring can scan the corresponding definition and define it as a bean in the corresponding bean container.

@Component
public class Hello {
	
}

When Spring scans such a class marked with @Component, it will define a bean whose beanName is our class name by default, corresponding to a lowercase first letter. So in the above example, a bean of type Hello and beanName "hello" will be generated by default. Of course, we can also specify the beanName of the bean to be generated through the value attribute of @Component. In the following example, the beanName of the corresponding generated bean is specified as "abc" through the value attribute.

@Component("abc")
public class Hello {
	
}

In addition to @Component, Spring also supports scanning for @Controller, @Service and @Repository annotations by default. They can be used to annotate specific beans, such as @Controller is usually annotated on a class in the Controller layer, @Service is annotated on a class in the Service layer, and then @Repository is annotated on a class in the Dao layer. These are just unwritten rules. If the user wishes, we can also use @Controller, @Component, etc. on the Service layer to mark them, and Spring will define them as corresponding beans after scanning. One of the main reasons why there are so many different annotations can be used to define beans is that we can distinguish different bean types through different annotations, and then we can let Spring scan only specific types of annotations when scanning. When we use SpringMVC, we often let the ApplicationContext corresponding to SpringMVC only scan @Controller, and then let the traditional ApplicationContext scan only other types of annotations except @Controller to define different types of beans in different bean containers. In this way, some operations in a specific bean container will only work on some beans. @Controller, @Service and @Repository can also specify the beanName corresponding to the bean definition to be generated through the value attribute. By default, the first letter of the current Class name is lowercase.

16.2 Defining your own @Component

We can also define our own annotations through @Component, that is, use @Component to annotate our own annotations, so that when we use a custom annotation to annotate a Class, Spring will define it as a bean by default. As follows, we define a @MyComponent, and then mark it with @Component. Of course, it is also possible to use @Controller, @Service, and @Repository for annotation. In fact, they are also defined using @Component. marked.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface MyComponent {

	public String value() default "";
	
}

After that, we can use @MyComponent to annotate the Class, and Spring will define them as a bean by default when scanning.

@MyComponent("abc")
public class Hello {
	
}

In fact, we can also let Spring scan for custom annotations and let it define the class marked with the custom annotation as the corresponding bean, and our custom annotation can be marked without using the original supported annotations such as @Component. Of course, this usage also requires some configuration, mainly to tell Spring which annotations to scan. This part will be explained in the subsequent explanation of filters during scanning.

16.3 Setting the Scanning Classpath

In fact, using @Component and other annotations on the Class is not enough for Spring to scan and define them as a bean. We have to tell Spring which classpath to scan via configuration. First, we must introduce the context namespace in Spring's configuration file, and then <context:component-scan/>enable Spring to scan @Component annotations through tag definitions. <context:component-scan/>The tag has an attribute that must be specified, base-package, which is used to specify the base package path we need to scan. After specifying, Spring will scan the package specified by base-package and its descendants. If multiple base packages need to be specified, they can be separated by commas. The following example means that Spring will scan the com.app.service package and its descendant packages on the classpath, as well as all the classes under the com.app.dao package and its descendant packages to find the Classes annotated with annotations such as @Component defined as the corresponding bean.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="com.app.service,com.app.dao" />	

</beans>

After defining the <context:component-scan/>tag, Spring will implicitly enable support for annotations by default, that is, the use of annotations such as @Autowired introduced earlier, so after using this tag, we do not need to explicitly define it in the Spring configuration file <context:annotation-config/>. This can be defined through the annotation-config property, which is true by default, and can be changed to false to disable automatic enablement of annotation support.

<context:component-scan base-package="com.app" annotation-config="true"/>	

In addition to the attribute base-package that must be specified, the <context:component-scan/>following attributes can also be specified.

  • resource-pattern: Indicates the form of the class that can be automatically detected, the default is “**/*.class”, that is, all class files. This is only used to tell Spring which files need to be scanned, not to automatically define them as corresponding beans. This needs to be distinguished from the filter that needs to be introduced later.
  • use-default-filters: Indicates that the default filter is used. <context:component-scan/>Which classes will be automatically registered to the bean container is controlled by the corresponding filter. The value of this property defaults to true, that is, the default filter is used by default. The default filter will automatically register the classes marked with @Component, @Controller, @Service and @Repository, including the classes marked with the annotations marked by these four annotations, into the bean container.
  • annotation-config: Whether to enable support for annotations, that is, implicitly enabled <context:annotation-config/>, the default is true.
  • name-generator: The default beanName generator, that is, how the automatically registered bean will use the default beanName when no beanName is explicitly specified. By default, the short name of Class will be used, that is, the class name without the package name, and the first letter will be lowercase as the name of the current bean. Users can org.springframework.beans.factory.support.BeanNameGeneratorchange the corresponding strategy by implementing the interface and specifying it as the current name-generator.
  • scope-resolver: Specifies the ScopeMetadataResolver used to resolve the scope defined by the bean. By default, it will be resolved through the AnnotationScopeMetadataResolver, and the resolver will resolve the corresponding scope according to the @Scope annotation marked on the class. By default, those without @Scope are singletons.
  • scoped-proxy: Indicates whether the corresponding proxy needs to be generated for the automatically detected beans that need to be added to the bean container. The default is not to generate. The optional values ​​are "no", "interfaces" and "targetClass", which correspond to not generated, generated according to interface, and generated according to target class, respectively. This is very necessary for scopes that need to use proxies, such as request, session, etc. For more details, please refer to the previous article dedicated to scope.

16.4 Using @Scope to specify scope

When Spring <context:component-scan/>automatically detects the bean definition that needs to be added to the bean container, it will add the detected class singleton form to the bean container by default. If the user wishes to use another type of scope, it can be specified by using @Scope on the class definition. The specific scope is specified by the value attribute of @Scope, which is a singleton by default. The following is an example of specifying the scope of the corresponding bean as prototype through @Scope, that is, in the form of multiple instances, each time a request is made from the bean container, a brand new bean object will be obtained.

@Component
@Scope("prototype")
public class Hello {
	
}

In addition, we can also specify the proxy mode of the current bean through the proxyMode attribute of @Scope. It corresponds to an enumeration of type ScopedProxyMode. The optional values ​​are DEFAULT, NO, INTERFACES and TARGET_CLASS. The default is no proxy. The effect of DEFAULT is equivalent to that of NO.

 

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class Hello {
	
	
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326341834&siteId=291194637