In learning the Java Spring Framework, there is a difficult problem to understand in the process of learning AOP: Customizing annotations, and then parsing annotations for permission control.
Permissions control: Because in some projects, some methods of the service layer require different permissions to access. Therefore, permission control is required.
So, I've written a small example to look at the specific implementation process.
implementation scenarios: 1. Customize an annotation privilegeinfo, using this annotation to configure permissions for the methods in the service layer
2. Write an annotation parser annotationparse. Parsing annotations @privilegeinfo (name= "*")
(The annotation parser should parse the value of the name attribute in the @privilegeinfo) 3. In AOP, depending on the value of the privilegeinfo annotation, whether the user has access to the target method, there is access to the target, there is no hint
Key Technologies : Custom annotations + annotation parsing +spring AOP
The final implementation of the directory structure:
UML Class Structure diagram:
Specific implementation steps:
1. Custom Annotations
Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;
/**
* Custom Annotations
* @author Yangguang * *
/@Target (Elementtype.method)//The purpose of the annotations: Method
@Retention (retentionpolicy.runtime)//annotations are present in the class bytecode file and can be retrieved to public
@interface Privilegeinfo {
//permissions by reflection at run time
String name () default "";
}
After you have finished customizing the annotations, you also need to write a note parser that returns the name value of the annotation privilegeinfo setting on the target method.
2. Annotation parser
Import Java.lang.reflect.Method;
/**
* Permission Annotation Parser
* The function of this parser is: if there is a privilegeinfo annotation on the parsing target method, the parser resolves the name value in this annotation (the value of the permission)
* @author Yangguang
*
*
/public class Annotationparse {
/**
* parsing annotations
* @param targetclassname target Class (class form)
* @param MethodName the target method (which method is called on the client, MethodName represents which method)
* @return
* @throws Exception */public
static String Parse (Class targetclassname,string methodName) throws exception{
//Get target method Methods
= Targetclassname.getmethod (methodName);
String methodaccess = "";
Determine if the target method has @privilegeinfo annotations
//@Privilege (name= "Saveperson")
if (Method.isannotationpresent ( Privilegeinfo.class) {
//Get annotations on the method
privilegeinfo privilegeinfo = method.getannotation ( Privilegeinfo.class);
Get the name value in the annotation
methodaccess = Privilegeinfo.name ();
}
return methodaccess;
}
}
3.
with custom annotations and parsers, it is time to write out the corresponding service layer and add this annotation to the method that you want to use access to. In general, the service layer contains both an interface and an implementation class.
Interface :
Package com.yangguang.aop.privilage.service;
/** *
User Business Interface
* @author Yangguang * */public
interface Personservice {
//on the target method that requires permission, Use privilegeinfo annotations public
void Saveperson ();
}
interface Implementation class:
Package Com.yangguang.aop.privilage.service.impl;
Import Com.yangguang.aop.privilage.annotation.PrivilegeInfo;
Import Com.yangguang.aop.privilage.dao.PersonDao;
Import Com.yangguang.aop.privilage.service.PersonService;
/** *
User Service Implementation
* @author Yangguang * * */Public
class Personserviceimpl implements Personservice {
Persondao Persondao;
public void Setpersondao (Persondao persondao) {
This.persondao = Persondao;
}
Configure Privilegeinfo annotation
@PrivilegeInfo (name= "Saveperson") public
void Saveperson () {
This.personDao.savePerson ();
}
}
4. above we have written: custom annotations + annotation parser +service layer. However, sometimes permissions need to meet some conditions: such as name, age, VIP level, and so on, so we need to encapsulate this information in a bean. (The following example value encapsulates an attribute name).
Package Com.yangguang.aop.privilage.bean;
/**
* Encapsulates user rights information (only name is encapsulated here)
* @author Yangguang * */Public
class Privilege {
private String Name;
Public String GetName () {
return name;
}
public void SetName (String name) {
this.name = name;
}
}
5. Writing Tangent lines
In the facets, we use surround notifications, and before we call the target method, we need to do the following in the program:
The Privilegeinfo annotation on the existing target method is configured with permissions that match the permissions that the user has.
A) If the match succeeds, the user is assumed to have this permission to use the target method
b) If the match fails, give a hint that is not authorized to access
Package com.yangguang.aop.privilage.annotation;
Import Java.lang.reflect.Method;
/**
* Permission Annotation Parser
* The function of this parser is: if there is a privilegeinfo annotation on the parsing target method, the parser resolves the name value in this annotation (the value of the permission)
* @author Yangguang
*
*
/public class Annotationparse {
/**
* parsing annotations
* @param targetclassname target Class (class form)
* @ Param methodName Target Method (which method is called on the client, MethodName represents which method)
* @return
* @throws
Exception
*/Public Static String Parse (Class targetclassname,string methodName) throws exception{
//Get target method Methods
= Targetclassname.getmethod (methodName);
String methodaccess = "";
Determine if the target method has @privilegeinfo annotations
//@Privilege (name= "Saveperson")
if (Method.isannotationpresent ( Privilegeinfo.class) {
//Get annotations on the method
privilegeinfo privilegeinfo = method.getannotation ( Privilegeinfo.class);
Get the name value in the annotation
methodaccess = Privilegeinfo.name ();
}
return methodaccess;
}
}
6.Spring configuration file ApplicationContext. XML
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns= "Http://www.springframework.org/schema/beans" Xmlns:xs
I= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "Http://www.springframework.org/schema/context" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "Http://www.springframework.org/schema /beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework. Org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd HTTP://WWW.S PRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop-3.2.xsd "> &L T;bean id= "Persondao" class= "Com.yangguang.aop.privilage.dao.impl.PersonDaoImpl" ></bean> <bean id= " Personservice "class=" Com.yangguang.aop.privilage.service.impl.PersonServiceImpl "> <property name=" Persondao "> <ref bean=" Persondao "/> </property> </bean> <bean id= "Accessmethod" class= " Com.yangguang.aop.privilage.aspect.AccessTargetObject "></bean> <aop:config> <!--define a pointcut expression,
Used to determine which classes require proxy execution (* com.yangguang.aop.privilage.service.impl.*.* (..)) All methods that represent all the classes within the package will be proxied-<aop:pointcut expression= "Execution (* com.yangguang.aop.privilage.service.impl.*.* (
..))" Id= "perform"/> <aop:aspect ref= "Accessmethod" > <aop:around method= "Accessmethod" pointcut-ref= "perform" /> </aop:aspect> </aop:config> </beans>
7. Test class
Package com.yangguang.aop.privilege.test;
Import java.util.List;
Import Org.junit.Test;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
Import Com.yangguang.aop.privilage.aspect.AccessTargetObject;
Import Com.yangguang.aop.privilage.bean.Privilege;
Import Com.yangguang.aop.privilage.service.PersonService;
public class Privilegetest {
@Test public
void Test () {
ApplicationContext context =
New Classpathxmlapplicationcontext ("Applicationcontext.xml");
Initialize the user's permissions
accesstargetobject targetObject = (accesstargetobject) context.getbean ("Accessmethod");
list<privilege> privileges = Targetobject.getuserprivilege ();
Privilege Privilege = new Privilege ();
Privilege.setname ("Savperson");
Privileges.add (privilege);
Personservice Personservice = (personservice) context.getbean ("Personservice");
Personservice.saveperson ();
}
}
Output information: