Annotations in Spring can be roughly divided into two categories:
1) Annotations related to spring bean containers, or bean factories;
2) Annotations related to springmvc.
The annotations related to spring's bean container include: @Required, @Autowired, @PostConstruct, @PreDestory, and the annotations in the JSR-330 standard javax.inject.* that Spring 3.0 has been supported (@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton).
SpringMvc related annotations include: @Controller, @RequestMapping, @RequestParam, @ResponseBody, etc.
To understand the annotations in Spring, you must first understand the annotations in Java.
1. Annotations in Java
Annotations have begun to be introduced in Java 1.5. The one we are most familiar with should be: @Override, which is defined as follows:
/** * Indicates that a method declaration is intended to override a * method declaration in a supertype. If a method is annotated with * this annotation type compilers are required to generate an error * message unless at least one of the following conditions hold: * The method does override or implement a method declared in a * supertype. * The method has a signature that is override-equivalent to that of * any public method declared in Object. * * @author Peter von der Ahé * @author Joshua Bloch * @jls 9.6.1.4 @Override * @since 1.5 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {}From the annotation, we can see that the function of @Override is to prompt the compiler that the method used by @Override annotation must override the parent class or a method of the same name in java.lang.Object. We see that @Target and @Retention are used in the definition of @Override. They are the so-called "meta-annotations" - they are the annotations that define the annotations, or the annotations that annotations (dizzy...). Let's take a look at @Retention
/** * Indicates how long annotations with the annotated type are to * be retained. If no Retention annotation is present on * an annotation type declaration, the retention policy defaults to * RetentionPolicy.CLASS. */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value();}@Retention is used to prompt how long the annotation is retained. There are three values:
public enum RetentionPolicy { /** * Annotations are to be disclosed by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME} RetentionPolicy.SOURCE is retained at the source code level and abandoned by the compiler (@Override is this kind); RetentionPolicy.CLASS is retained at the compiled class file level by the compiler, but discarded by the virtual machine;
RetentionPolicy.RUNTIME is reserved until runtime and can be read by reflection.
Look at @Target:
package java.lang.annotation;/** * Indicates the contexts in which an annotation type is applicable. The * declaration contexts and type contexts in which an annotation type may be * applicable are specified in JLS 9.6.4.1, and denoted in source code by enum * constants of java.lang.annotation.ElementType * @since 1.5 * @jls 9.6.4.1 @Target * @jls 9.7.4 Where Annotations May Appear */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Target {/** * Returns an array of the kinds of elements an annotation type * can be applied to. * @return an array of the kinds of elements an annotation type * can be applied to */ElementType[] value();}@Target is used to prompt the use of this annotation, and the values are:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * @since 1.8 */ TYPE_USE}Indicates where this annotation can be used separately: 1) class, interface, annotation, enum; 2) attribute domain; 3) method; 4) parameters; 5) constructor; 6) local variables; 7) annotation type; 8) package
so:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {}It means that @Override can only be used on methods, retained at the source code level, processed by the compiler, and then discarded.
There is also a frequently used meta annotation @Documented:
/** * Indicates that annotations with a type are to be documented by javadoc * and similar tools by default. This type should be used to annotate the * declarations of types whose annotations affect the use of annotated * elements by their clients. If a type declaration is annotated with * Documented, its annotations become part of the public API * of the annotated elements. */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Documented {}Indicates whether annotations can be processed by javadoc and retained in the document.
2. Customize and process custom annotations with meta annotations
With meta annotations, I can use it to customize the annotations we need. Combining custom annotations and AOP or filters is a very powerful weapon. For example, annotations can be used to achieve fine-grained control of permissions - use permission annotations on classes or methods, and then intercept them in AOP or filters. Here is an implementation of annotation about login permissions:
/** * No login annotation required*/@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface NoLogin {}We have customized annotation @NoLogin, which can be used on methods and classes. The annotation is retained until the runtime and can be read by reflection. The meaning of this annotation is: the class or method annotated by @NoLogin can be accessed even if the user is not logged in. The following is the process of the annotation:
/** * Check login interceptor* If you do not need to check the login, you can add @NoLogin to the method or controller */public class CheckLoginInterceptor implements HandlerInterceptor {private static final Logger logger = Logger.getLogger(CheckLoginInterceptor.class);@Override public Boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {logger.warn("The current operation handler is not HandlerMethod=" + handler.getClass().getName() + ",req=" + request.getQueryString());return true;}HandlerMethod handlerMethod = (HandlerMethod) handler;String methodName = handlerMethod.getMethod().getName();// Determine whether you need to check login NoLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class); if (null != noLogin) {if (logger.isDebugEnabled()) {logger.debug("Current operation methodName=" + methodName + "No need to check login");} return true;}noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class); if (null != noLogin) {if (logger.isDebugEnabled()) {logger.debug("Current operation methodName=" + methodName + "No need to check login");} return true;}if (null == request.getSession().getAttribute(CommonConstants.SESSION_KEY_USER)) {logger.warn("Current operation" + methodName + "User not logged in, ip=" + request.getRemoteAddr());response.getWriter().write(JsonConvertor.convertFailResult(ErrorCodeEnum.NOT_LOGIN).toString());// Return error message return false;}return true;}@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}}Above we define a login interceptor, first using reflection to determine whether the method is annotated by @NoLogin:
NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);
Then determine whether the class is annotated by @NoLogin:
noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);
If it is annotated, it returns true. If it is not annotated, it is determined whether it has been logged in. If it is not logged in, it returns error messages to the foreground and false. This is a simple example of using annotations and filters for permission processing. If we expand, we can use annotations to indicate that a certain method or class can only be accessed by users with a certain role or permissions, and then judge in the filter.
3. Annotations related to spring bean container
1) @Autowired is the annotation we use the most. In fact, autowire=byType is an automatic injecting dependency based on the type (annotation-based dependency injection), which can be used in the domain, method, and constructor.
2) @Qualifier is autowire=byName. When the @Autowired annotation determines that multiple bean types are the same, you need to use @Qualifier("xxBean") to specify the id of the dependent bean:
@Controller@RequestMapping("/user")public class HelloController { @Autowired @Qualifier("userService") private UserService userService;3) @Resource belongs to the JSR250 standard and is used in the domain and methods. It is also a dependency injection of the byName type. Usage method: @Resource(name="xxBean"). @Resource without parameters The default value class name has lowercase.
4) Annotations in JSR-330 standard javax.inject.* (@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton). @Inject is equivalent to @Autowired, @Named is equivalent to @Qualifier, and @Named is also used in the class as @Component.
5) @Component, @Controller, @Service, @Repository, These annotations are different from the above annotations. The above annotations are injected into the depended beans, and the function of these annotations is to produce beans. These annotations are annotated on the class, annotating the class into beans one by one in the spring bean factory. @Controller, @Service, @Repository is basically @Component with more refined semantics.
6) @PostConstruct and @PreDestroy are not used for dependency injection, but for the life cycle of the bean. Similar to init-method(InitializeingBean) destory-method(DisposableBean)
4. Processing of annotations in spring
The processing of annotations in spring is basically done by implementing the interface BeanPostProcessor:
public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}Related processing classes are: AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor
These processing classes can be implicitly configured into the spring container through <context:annotation-config/>. These are all processing of dependency injection, as well as processing of production bean annotations (@Component, @Controller, @Service, @Repository):
<context:component-scan base-package="net.aazj.service,net.aazj.aop" />
These are done by specifying the scanned base packet path, scanning them into spring bean containers. Note that context:component-scan will also configure AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor by default. Therefore <context:annotation-config/> can be omitted. In addition, context:component-scan can also scan the @Aspect style AOP annotation, but it is necessary to add <aop:aspectj-autoproxy/> to the configuration file for cooperation.
5. The difference between Spring annotations and JSR-330 standard annotations:
Summarize
The above is all about quickly understanding the various annotations in spring. I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!