After learning Java will encounter a lot of annotations, have loaded JavaBean annotations: @Component, @Service, @Controller; there is a note @value to get the value of the configuration file; Requestbody. With these annotations, spring scans these components to provide the relevant services. How do you customize annotations to meet your specific services?
"Turn" http://blog.csdn.net/mafan121/article/details/50212137
"Turn" http://www.jianshu.com/p/7c2948f64b1c; Deep spring: Custom annotation loading and use
"Go" http://www.jianshu.com/p/9d4bd8955d1a;spring the use and parsing of custom annotations
Welcome to GitHub download code
First, understand the meta-annotations
Meta-annotations, meta: atoms, which make up the underlying annotations of other annotations. Java provides 4 types of meta-annotations for annotating other annotations.
The @Target ({elementtype.type})//is used to describe the use of annotations, and compilation fails when out of scope. Value type (elementtype): 1.CONSTRUCTOR: Used to describe the constructor 2.FIELD: Used to describe a domain (member variable) 3.local_variable: Used to describe a local variable 4. Method: Used to describe methods 5.PACKAGE: Used to describe the package 6.PARAMETER: Used to describe the parameter 7.TYPE: Used to describe the class, interface (including annotation type) or enum declaration @retention ( Retentionpolicy.runtime)//describes the life cycle of annotations, which is the effective scope of annotations. Value range (retentionpolicy): 1.SOURCE: In the source file, only in the Java file, the class file will be stripped of annotations. 2.CLASS: Takes effect in the class file, remains in the class file, and cannot be annotated at run time. 3.RUNTIME: Takes effect at runtime, remains in the class file and can be obtained through the reflection mechanism at run time. @Documented//To display this annotation information when specifying the Javac build API. @Inherited //indicates that the annotation can be inherited by subclasses, and subclasses can inherit annotations from the parent class. By default, subclasses do not inherit the parent annotation.
Second, read the annotations
Java interprets annotations through the reflection mechanism, Java adds a annotatedelement interface under the Java.lang.reflect package, and Annotatedelement is the parent interface for all annotation elements. All annotation elements can be reflected by a class to get the Annotatedelement object, which has 4 methods to access the annotation information.
(1) <t extends annotation> T getannotation (class<t> annotationclass) Returns a specified type of annotation that exists on the program element, If the type annotation does not exist, NULL is returned. (2) annotation[] getannotations (): Returns all annotations that exist on the program element. (3)boolean isannotationpresent (class<?extends annotation> annotationclass) Evaluates whether the program element contains annotations of the specified type, or returns true if present, otherwise false. (4) annotation[] getdeclaredannotations () returns all comments that exist directly on this element. Unlike other methods in this interface, the method ignores inherited annotations. (if no comment exists directly on this element, an array of zero length is returned.) The caller of the method can arbitrarily modify the returned array, which does not have any effect on the array returned by other callers.
Third, custom JavaBean annotations.
Custom annotations are
package mydefinecomponent; import java.lang.annotation.Documented; 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) @Documented public @ interface mydefinecomponent {String value () default ""
The Java custom scanner inherits Classpathscanningcandidatecomponentprovider,classpathbeandefinitionscanner and adds custom TypeFilter internally.
Package Mydefinecomponent;import Java.util.set;import Org.springframework.beans.factory.support.beandefinitionregistry;import Org.springframework.beans.factory.support.genericbeandefinition;import Org.springframework.context.annotation.classpathbeandefinitionscanner;import Org.springframework.core.type.filter.annotationtypefilter;import Org.springframework.beans.factory.annotation.annotatedbeandefinition;import Org.springframework.beans.factory.config.beandefinitionholder;public Final class Scanner extends Classpathbeandefinitionscanner {public Scanner (Beandefinitionregistry registry) {Super (registry);//TODO Auto-generated constructor stub}public void Registerdefaultfilters () {This.addincludefilter (new Annotationtypefilter (Mydefinecomponent.class));} Public set<beandefinitionholder> Doscan (String ... basepackages) {set<beandefinitionholder> Beandefinitions = Super.doscan (basepackages); for (Beandefinitionholder holder:beandefinitions) { Genericbeandefinition definition = (genericbeandefinition) holder.getbeandefinition ();d efinition.getpropertyvalues (). Add ("Innerclassname", Definition.getbeanclassname ());d Efinition.setbeanclass (Factorybeantest.class);} return beandefinitions;} public boolean iscandidatecomponent (Annotatedbeandefinition beandefinition) {return super.iscandidatecomponent ( beandefinition) && Beandefinition.getmetadata (). Hasannotation (MyDefineComponent.class.getName ());}}
Applicationcontextaware is an interface under the Org.springframework.context package that gets the context of spring, which is the ability to get to each bean in spring's IOC container by implementing this interface.
Package Mydefinecomponent;import Org.springframework.beans.beansexception;import Org.springframework.beans.factory.config.beanfactorypostprocessor;import Org.springframework.beans.factory.config.configurablelistablebeanfactory;import Org.springframework.beans.factory.support.beandefinitionregistry;import Org.springframework.context.applicationcontext;import Org.springframework.context.ApplicationContextAware; Import org.springframework.stereotype.Component; @Componentpublic class Beanscannerconfigurer implements Beanfactorypostprocessor, Applicationcontextaware{private applicationcontext applicationcontext; @Overridepublic void Setapplicationcontext (ApplicationContext applicationcontext) throws beansexception {This.applicationcontext = ApplicationContext;} @Overridepublic void Postprocessbeanfactory (Configurablelistablebeanfactory beanfactory) throws Beansexception { Scanner Scanner = new Scanner ((beandefinitionregistry) beanfactory); Scanner.setresourceloader ( This.applicationcontext); scanner.Scan ("Mydefinecomponent");}}
Factorybean is one of the more important classes in spring. The normal JavaBean is to use the instance of the class directly, but if a bean inherits this excuse, it can customize the contents of the instance through the GetObject () method, and in Factorybeantest's GetObject (), the method of the original class is proxied. A method for customizing the class.
Package Mydefinecomponent;import Org.springframework.beans.factory.factorybean;import Org.springframework.beans.factory.initializingbean;import Org.springframework.cglib.core.SpringNamingPolicy; Import Org.springframework.cglib.proxy.enhancer;public class Factorybeantest<t> implements Initializingbean, factorybean<t> {private string innerclassname;public void Setinnerclassname (String innerclassname) { This.innerclassname = Innerclassname;} @Overridepublic void Afterpropertiesset () throws Exception {//TODO auto-generated method stub} @Overridepublic T Getobjec T () throws Exception {Class innerclass = Class.forName (Innerclassname), if (Innerclass.isinterface ()) {return (t) Interfaceproxy.newinstance (innerclass);} else {Enhancer enhancer = new enhancer (); Enhancer.setsuperclass (innerclass); Enhancer.setnamingpolicy ( springnamingpolicy.instance); Enhancer.setcallback (new Methodinterceptorimpl ()); return (T) enhancer.create ();}} @Overridepublic class<?> Getobjecttype () {try {return CLass.forname (innerclassname);} catch (ClassNotFoundException e) {e.printstacktrace ();} return null;} @Overridepublic Boolean Issingleton () {//TODO auto-generated method Stubreturn true;}}
Package Mydefinecomponent;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.lang.reflect.proxy;public class Interfaceproxy implements Invocationhandler {@Overridepublic Object invoke ( Object Proxy, method, object[] args) throws Throwable {System.out.println ("ObjectProxy execute:" + method.getname ( ); return Method.invoke (proxy, args);} public static <T> T newinstance (class<t> innerinterface) {ClassLoader ClassLoader = Innerinterface.getclassloader (); Class[] interfaces = new class[] {innerinterface};interfaceproxy proxy = new Interfaceproxy (); return (T) proxy.newproxyi Nstance (ClassLoader, interfaces, proxy);}}
Package Mydefinecomponent;import Java.lang.reflect.method;import Org.springframework.cglib.proxy.methodinterceptor;import Org.springframework.cglib.proxy.methodproxy;public Class Methodinterceptorimpl implements methodinterceptor{@Overridepublic object Intercept (Object o, method, Object[] Objects,methodproxy methodproxy) throws Throwable {System.out.println ("Methodinterceptorimpl:" + Method.getname ()); return Methodproxy.invokesuper (O, objects);}}
Test code:
Package Mydefinecomponent, @MyDefineComponentpublic class ScanClass1 {public void print () {System.out.print (" Scanclass1 ");}}
Package Mydefinecomponent;import Org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Mydefinecomponenttest {public static void main (string[] args) {Annotationconfigapplicationcontext acc = new Annotationconfigapplicationcontext ("Mydefinecomponent"); ScanClass1 Scanclass = Acc.getbean (Scanclass1.class); Scanclass.print ();}}
Output:
Methodinterceptorimpl:printscanclass1
Three, custom annotations, you can quickly get all the classes or methods or properties that use the annotation, as well as the values within the annotations through spring.
To customize an annotation:
Package Com.my.annotation;import Java.lang.annotation.documented;import Java.lang.annotation.elementtype;import Java.lang.annotation.retention;import Java.lang.annotation.retentionpolicy;import java.lang.annotation.Target;@ Target ({elementtype.type, elementtype.method})//Can be used on methods or classes above @retention (retentionpolicy.runtime) @Documentedpublic @interface Fooish {string[] tags () default {"All"};}
Parsing features for custom annotations
Package Com.my.annotation;import Java.lang.reflect.method;import Java.util.arraylist;import java.util.Arrays; Import Java.util.list;import Java.util.map;import Org.springframework.beans.beansexception;import Org.springframework.beans.factory.initializingbean;import Org.springframework.context.applicationcontext;import Org.springframework.context.applicationcontextaware;import org.springframework.stereotype.component;@ Componentpublic class Myfooishhandler implements Applicationcontextaware, initializingbean{private ApplicationContext ApplicationContext; Private list<string> allfooish = new arraylist<> (), @Overridepublic void Afterpropertiesset () throws Exception {scanfooishclass (); Scanfooishmethod (); System.out.println (allfooish);} /** * Find the method with Fooish annotations */private void Scanfooishmethod () throws Exception{final map<string, object> permissionmap = Applicationcontext.getbeanswithannotation (Fooish.class); System.out.println ("This is Permissionmap" + perMissionmap.tostring ()); For (final Object permissionObject:permissionMap.values ()) {final class<? extends object> Permissioncl The Permissionobject.getclass (); Final Fooish annotation = permissionclass.getannotation (Fooish.class); if (annotation! = null) {Allfooish.addall (Arrays.aslist (Annotation.tags ())); }}}private void Scanfooishclass () throws Exception{final map<string, object> controllermap = ApplicationCont Ext.getbeanswithannotation (Fooish.class); For (final Object controllerObject:controllerMap.values ()) {final class<? extends object> CONTROLLERCL The Controllerobject.getclass (); For (Method method:controllerClass.getDeclaredMethods ()) {Fooish Fooish = method.getannotation (fooish.cl ); if (Fooish! = null) {Allfooish.addall (Arrays.aslist (Fooish.tags ())); }}} @Overridepublic void Setapplicationcontext (ApplicationContext applicationcontext) throws Beansexception { This.applicationcontext = ApplicationContext;}}
Test:
Package Com.my.controller;import Java.io.file;import Java.io.ioexception;import java.util.list;import Javax.annotation.resource;import Javax.servlet.servletoutputstream;import Javax.servlet.http.HttpServletResponse ; Import Org.springframework.beans.factory.annotation.value;import Org.springframework.web.bind.annotation.requestmapping;import Org.springframework.web.bind.annotation.requestmethod;import Org.springframework.web.bind.annotation.requestparam;import Org.springframework.web.bind.annotation.restcontroller;import Com.my.annotation.fooish;import Com.my.model.student;import Com.my.service.firstpageservice;import com.my.service.qrcodeutil;@ Restcontroller@fooish (tags={"This_is_class"}) public class Firstpagecontroller {@Value (Value = "${erweima.location:d :/workspaces/myeclipse 2015/entrance/src/main/resources/erweima.png} ") private String Imgpath; @Resourceprivate Firstpageservice firstpageservice; @RequestMapping (value = "/", method = Requestmethod.get) @Fooish (tags={"This_is_ Method "}) StRing Home () {return firstpageservice.getstring ();}}
"Reference Blog"
1, http://blog.csdn.net/mafan121/article/details/50212137
2, http://www.jianshu.com/p/7c2948f64b1c; in-depth spring: custom annotation loading and use
3, the use and resolution of http://www.jianshu.com/p/9d4bd8955d1a;spring custom annotations
Java custom annotations and annotations parsing instances