java 动态署理及自定义标注使用例子
java 动态代理及自定义标注使用例子
java中动态代理,在实际应用中有着很大的作用,譬如在一些类似的操作之前进行某种逻辑处理,或者在操作之后进行记录操作日志 用java的代理给类似的操作抽象出相同的代理部分,不同的信息用注解之类的统一模板,会给应用带来很大方便。如下例中用注解来控制是否允许删除的小例子。
自定义注解@Scope
package my.service; import java.lang.annotation.Retention; /** * @author Lyon Yao * */ @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Scope { String value(); }
动态代理类,在类中根据注解判断是否执行
package my.aop; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import my.service.Scope; /** * 代理类 * @author Lyon Yao * */ public class ProxyFactory implements InvocationHandler{ private Object targetObject; public Object instanceProxy(Object object){ this.targetObject=object; return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),this.targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // return this.invoke(method, args); System.out.println("pa"); Class<?> [] parameterTypes=method.getParameterTypes(); Method tmp_m = this.targetObject.getClass().getMethod(method.getName(),parameterTypes ); Annotation[] anns=tmp_m.getAnnotations(); Object result=null; if(anns!=null&&anns.length>0){ for(int i=0;i<anns.length;i++){ Annotation ann=anns[i]; if(ann.annotationType().equals(Scope.class)){ Scope gen=(Scope) ann; String values=gen.value(); if(values==null){ return this.invoke(method, args); }else { if(values.equals("yes")){ return this.invoke(method, args); }else if(values.equals("not")){ return result; }else{ return this.invoke(method, args); } } }else{ return this.invoke(method, args); } } }else{ return this.invoke(method, args); } return result; } private Object invoke(Method method,Object agrs[]) throws Throwable{ return method.invoke(this.targetObject, agrs); } }
代理接口
package my.service; /** * 用户信息操作(接口) * @author Lyon Yao * */ public interface UerService { /** * 保存 */ public void save(String user); /** * 获取 * @return */ public String get(); /** * 删除 */ public void delete(); }
接口实现类
package my.service.impl; import my.service.Scope; import my.service.UerService; /** * 用户信息管理(实现) * @author Lyon Yao * */ public class UserServiceImpl implements UerService { private String user=null; public UserServiceImpl(String user) { super(); this.user = user; } public UserServiceImpl() { super(); } @Scope(value="not") public void delete() { System.out.println(user+"deleted"); } @Scope(value="yes") public String get() { System.out.println(user+"geted"); return user; } @Scope(value="not") public void save(String user) { System.out.println(user+"saved"); } public String getUser() { return user; } }
利用junit进行测试
package my.aop.test; import my.aop.ProxyFactory; import my.service.UerService; import my.service.impl.UserServiceImpl; import org.junit.BeforeClass; import org.junit.Test; /** * @author Lyon Yao * */ public class UserServiceMethodControlTest { private static ProxyFactory proxy; @BeforeClass public static void setUpBeforeClass() throws Exception { proxy=new ProxyFactory(); } @Test public void testDelete(){ UerService userService=(UerService) proxy.instanceProxy(new UserServiceImpl("test")); userService.delete(); userService.get(); userService.save("mam"); } }
外面虽然进行了删除,获得,保存
但实际操作却打印出
pa
pa
testgeted
pa
说明只要获得执行了,看了这个小例子你有啥感想呢,在spring中方法的权限这里是不是这么做出来的呢?我不清楚,但猜可能是的。