非Spring 轻量级 AOP,没有 xml 配置,用于为方法编织注释
Non-Spring lightweight AOP without xml config for weaving annotations to methods
需要 运行 在某些注释的方法之前和之后。
不使用 spring,不使用 xml。是否可以使用我从 main() 设置的某种 AOP 引擎,以便可以在需要时调用它?我放一个方法手动调用一个求值方法也是可以的
示例:
public void doThis(@RequiredSecurityRole("admin") user){
doAOPStuff();
}
before()
从数据库获取并检查用户是否是管理员,如果不是管理员则抛出异常。
after()
登录数据库操作。
如何实现?
您可以使用 java.lang.reflex.Proxy class 自行完成此操作。它确实需要在接口中定义您代理的代码。
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DoItYourAop {
public static void main(String[] args) {
SaysHello saysHello = new SaysHelloImpl();
InvocationHandler logger = new LoggingProxy(saysHello);
SaysHello proxy = (SaysHello) Proxy.newProxyInstance(SaysHello.class.getClassLoader(),
new Class[]{SaysHello.class}, logger);
proxy.sayHello();
}
public interface SaysHello {
void sayHello();
void sayGoodbye();
}
public static class SaysHelloImpl implements SaysHello {
@Log
@Override
public void sayHello() {
System.out.println("Says Hello");
}
@Override
public void sayGoodbye() {
System.out.println("Says Goodbye");
}
}
@Retention(RUNTIME)
@interface Log {
}
public static class LoggingProxy implements InvocationHandler {
private final Object proxied;
public LoggingProxy(Object proxied) {
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method proxiedMethod = proxied.getClass().getMethod(method.getName(), method.getParameterTypes());
boolean log = proxiedMethod.isAnnotationPresent(Log.class);
if (log) {
System.out.println("Before");
}
Object result = method.invoke(proxied, args);
if (log) {
System.out.println("After");
}
return result;
}
}
}
需要 运行 在某些注释的方法之前和之后。
不使用 spring,不使用 xml。是否可以使用我从 main() 设置的某种 AOP 引擎,以便可以在需要时调用它?我放一个方法手动调用一个求值方法也是可以的
示例:
public void doThis(@RequiredSecurityRole("admin") user){
doAOPStuff();
}
before()
从数据库获取并检查用户是否是管理员,如果不是管理员则抛出异常。
after()
登录数据库操作。
如何实现?
您可以使用 java.lang.reflex.Proxy class 自行完成此操作。它确实需要在接口中定义您代理的代码。
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DoItYourAop {
public static void main(String[] args) {
SaysHello saysHello = new SaysHelloImpl();
InvocationHandler logger = new LoggingProxy(saysHello);
SaysHello proxy = (SaysHello) Proxy.newProxyInstance(SaysHello.class.getClassLoader(),
new Class[]{SaysHello.class}, logger);
proxy.sayHello();
}
public interface SaysHello {
void sayHello();
void sayGoodbye();
}
public static class SaysHelloImpl implements SaysHello {
@Log
@Override
public void sayHello() {
System.out.println("Says Hello");
}
@Override
public void sayGoodbye() {
System.out.println("Says Goodbye");
}
}
@Retention(RUNTIME)
@interface Log {
}
public static class LoggingProxy implements InvocationHandler {
private final Object proxied;
public LoggingProxy(Object proxied) {
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method proxiedMethod = proxied.getClass().getMethod(method.getName(), method.getParameterTypes());
boolean log = proxiedMethod.isAnnotationPresent(Log.class);
if (log) {
System.out.println("Before");
}
Object result = method.invoke(proxied, args);
if (log) {
System.out.println("After");
}
return result;
}
}
}