[Turn] spring custom annotations (annotation) to obtain notes and aop

First, let's introduce custom Java annotations.

During development, we implement the interface, there will be @Override, sometimes prompted to write @SuppressWarnings. In fact, this is Java-specific features, annotations.

注解就是某种注解类型的一种实例,我们可以把它用在某个类上进行标注。下面这张图解释注解都是什么?

image

Annotations can be seen on FIG roughly divided into three: a meta-annotation, the annotation tag, General Notes;

This one the other I do not introduced, we are here mainly talk about how to define your own notes, before that we need to understand the syntax definitions standard metadata annotations and annotations.
Meta-annotation role is responsible for other annotation notes. Java5.0 standard defines four meta-annotation type, which are used to provide other types of annotation specified. Java5.0 defined meta-annotation:

1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited

@Target
Annotation @Target illustrates the modified target range: Annotation may be used for packages, types (classes, interfaces, enumerations, Annotation type), a member type (method, constructor, member variables enumerated value), and the method parameters local variables (e.g., variable loop, catch parameters). Use a target in the Annotation type declaration can be more clear that it modifies the target.
Action: is used to describe use of annotations (i.e.: annotations are described may be used in any place)
Value (ElementType) are:
  1. CONSTRUCTOR: constructor is used to describe
  2. FIELD: descriptor for
  3. LOCAL_VARIABLE: local variables used to describe the
  4. METHOD: The method described for
  5. PACKAGE: package used to describe
  6. PARAMETER: parameters used to describe the
  7. TYPE: used to describe a class, an interface (including type of annotation), or an enum declaration
@Retention
@Retention defines the length of time that is reserved Annotation: Some Annotation appear only in the source code, the compiler is discarded; others was compiled class files; compile Annotation in the class file may be virtual machine ignored, while others will be loaded when the class is read (note does not affect the implementation of the class, because of the use of the Annotation class and are separated). Using this meta-Annotation Annotation can limit the "life cycle."
Role: expressed the need to save the annotation information on what level, it is used to describe the life cycle of notes (ie: annotations are described effectively to what extent)
Value (RetentionPoicy) are:
  1. SOURCE: Effective in the source file (i.e., the source file retention)
  2. CLASS: valid class file (ie class reserved)
  3. RUNTIME: effective (ie reserved runtime) at runtime
 @Documented
@Documented used to describe other types of annotation should be as a member of the public API program is marked, it can be such a tool such as javadoc documentation. Documented is a marker annotation, no members.
 @Inherited
@Inherited meta-annotation is a marker annotation, @ Inherited describes a certain type of indexed is inherited. If using a modified @Inherited annotation type is used for a class, then this annotation is used in a subclass of this class.
Note: @Inherited annotation type is marked off class subclass inherits. Class does not inherit from annotation methods it from overloading it implements interface inheritance annotation, method.
When @Inherited annotation type annotation of the annotation is Retention RetentionPolicy.RUNTIME, the reflected API enhances this inheritance. If we use java.lang.reflect to query a @Inherited annotation type of annotation, reflecting code checks will start work: check the class and its parent class, until you find designated annotation types are found, or to reach the top class inheritance structure.

Custom annotation

@Interface use custom annotations automatically inherited java.lang.annotation.Annotation interfaces, complete other details automatically by the compiler. When defining notes, annotations can not inherit or other interfaces. @interface used to declare an annotation, each of which method is actually declares a configuration parameter. Name of the method is the name of the parameter, return type is the type parameter (return value type can only be a basic type, Class, String, enum). You can declare the default value of the parameter by default.
Custom annotation format:
public @interface annotation definition body name} {

   Supportable data type annotation parameters:
   1. All elementary data types (int, a float, Boolean, byte, Double, char, Long, Short)
   2. String Type
   3. Class Type
   4. enum type
   5. Annotation type
   6. The above an array of all types
  
  Annotation types inside the parameters of how the set:
  first, only with public or default (default) access to these two modifications, such as, String value (); here, the default method is set defaul type;.
  the first Second, the basic parameters members can only use the type byte, short, char, int, long, float, double, boolean eight basic data types and String, Enum, Class, annotations and other data types, as well as some types of this array. For example, String value (); here it is a member of parameters String;
  third, if only one member of parameters, it is best to set the parameter name "value", after adding parentheses Example: the following example FruitName notes only one parameter member .


Example of use:

CacheRedis.java

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheRedis { String key(); int expireTime() default 600; }

CacheService.java

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect @Component public class CacheService { Logger logger = LoggerFactory.getLogger(CacheService.class); @Pointcut(value = "@annotation(com.meizu.bro.service.test.CacheRedis)") public void pointCut(){} @Before(value = "pointCut() && @annotation(cacheRedis)") public void before(CacheRedis cacheRedis) { logger.info("the result of this method will be cached."); } @AfterReturning(value = "pointCut() && @annotation(cacheRedis)",returning = "result") public void after(CacheRedis cacheRedis,Object result) { String key = cacheRedis.key(); int expireTime = cacheRedis.expireTime(); //do something... logger.info("-----redis-----[key = " + key + "]"+"[expireTime = " + expireTime + "]"); logger.info("the result of this method is" + result + ",and has been cached."); } //@Around("pointCut() && @annotation(cacheRedis)") //public Object setCache(ProceedingJoinPoint joinPoint,CacheRedis cacheRedis) { // Object result = 1; // // Method method = getMethod(joinPoint);//自定义注解类 // //CacheRedis cacheRedis = method.getAnnotation(CacheRedis.class);//获取key值 // String key = cacheRedis.key(); // int expireTime = cacheRedis.expireTime(); // //获取方法的返回类型,让缓存可以返回正确的类型 // Class returnType =((MethodSignature)joinPoint.getSignature()).getReturnType(); // // logger.info("[key = " + key + "]"+"[expireTime = " + expireTime + "]"); // // return result; //} // //private Method getMethod(ProceedingJoinPoint joinPoint) { // //获取参数的类型 // Method method = null; // try { // Signature signature = joinPoint.getSignature(); // MethodSignature msig = null; // if (!(signature instanceof MethodSignature)) { // throw new IllegalArgumentException("该注解只能用于方法"); // } // msig = (MethodSignature) signature; // method = joinPoint.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes()); // } catch (NoSuchMethodException e) { // logger.error("annotation no sucheMehtod", e); // } catch (SecurityException e) { // logger.error("annotation SecurityException", e); // } // return method; //} } 

Test interface TestController.java

@Controller
public class TestController { @Autowired private TestService testService; @RequestMapping(value = "/test") public ModelAndView myTest() { int test = testService.test(10); return ViewUtil.buildStandardJsonViewByObj(test); } @RequestMapping(value = "/test1") public ModelAndView myTest1() { String yanyi = testService.test1("yanyi"); return ViewUtil.buildStandardJsonViewByObj(yanyi); } }

TestService.java

public interface TestYanyiService {
    int test(int i); String test1(String i1); }

TestServiceImpl.java

import org.springframework.stereotype.Service;

@Service
public class TestYanyiServiceImpl implements TestYanyiService { @Override @CacheRedis(key = "test",expireTime = 10) public int test(int i) { return 0; } @Override @CacheRedis(key = "test1") public String test1(String i1) { return i1; } }

After completion of the code, you need to import the file dependent in pom:

            <dependency>
                <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>

This one should pay attention to: the version aspectjweaver package and JDK versions are associated. If JDK 1.7 and above users, version requires aspectjweaver package can not be too low (JDK1.7 - aspectJ1.7.3 +). Otherwise it will error: error error at :: 0 can not find referenced pointcut.

Next, follows in the Spring configuration file

<!-- 启动对@AspectJ注解的支持 -->  
<aop:aspectj-autoproxy/> 

<!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller->  
<aop:aspectj-autoproxy proxy-target-class="true" />  

ok! Upon completion, test call interface, you can see the relevant section log print class front and rear of the control window. At this time, we will be able to realize their functions slightly inside. (I am here ready to implement redis caching feature.)

Guess you like

Origin www.cnblogs.com/exmyth/p/11495006.html