Java:基于注释的代码注入的简单技术? [英] Java: Simple technique for annotation-based code injection?

查看:24
本文介绍了Java:基于注释的代码注入的简单技术?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让这段代码正常工作?

登录控制.java

@Audit(AuditType.LOGON)公共无效登录(字符串用户名,字符串密码){//进行登录}

AuditHandler.java

public void audit(AuditType auditType) {//持续审计}

最终结果是,每次调用 login() 时,也会使用适当的审计类型调用 audit().

我想 AOP 可能是解决这个问题的方法,但我希望它尽可能简单(我通常看过的 AspectJ 教程有非常复杂的注释).

注意:我不想预先定义将调用审计的方法,我正在为可扩展框架编写此代码,其他人可能需要使用它.

解决方案

使用反射很容易,只需用@Audit 注释一个方法,就像 JUnit 中的测试运行器:

公共接口登录{无效登录(字符串名称,字符串密码);}公共类 LoginImpl 实现登录 {@Audit(handler = LoginHandler.class)公共无效登录(字符串名称,字符串密码){System.out.println("登录");}}

@Audit 定义为:

@Retention(RetentionPolicy.RUNTIME)@目标(元素类型.方法)公共@interface 审计{类处理程序();}

处理程序在哪里:

接口处理程序{无效句柄();}类 LoginHandler 实现了 Handler {公共无效句柄(){System.out.println("调用了处理程序!");}}

现在是真正的代码:

public class LoginFactory {私有静态类 AuditInvocationHandler 实现 InvocationHandler {私人最终登录 realLogin;公共审计调用处理程序(登录真实登录){this.realLogin = realLogin;}公共对象调用(对象代理,方法方法,对象 [] args)抛出 Throwable {方法 realMethod = realLogin.getClass().getMethod(方法.getName(),method.getParameterTypes());审计审计 = realMethod.getAnnotation(Audit.class);如果(审计!= null){audit.handler().newInstance().handle();}返回 method.invoke(realLogin, args);}}公共静态登录 createLogin() {返回(登录)Proxy.newProxyInstance(LoginFactory.class.getClassLoader(),new Class[]{Login.class},new AuditInvocationHandler(new LoginImpl()));}}

@测试:

 Login login = LoginFactory.createLogin();login.login("用户", "秘密");登录.注销();

输出:

<前>处理程序调用!登录登出

Is there a way to make this code work?

LogonControl.java

@Audit(AuditType.LOGON)
public void login(String username, String password) {
 // do login
}

AuditHandler.java

public void audit(AuditType auditType) {
 // persist audit
}

Endgame being, that each time login() is called, audit() is also called, with the appropriate audittype.

I imagine AOP is probably the solution to this, but I would like it to be as simple as possible (the AspectJ tutorials I've looked at normally have very convoluted annotations).

Note: I don't want to have to predefine the methods that will call audit, I'm writing this for an extensible framework, and others may need to use it.

解决方案

Using reflection is easy just annotate a method with @Audit, just like test runners in JUnit:

public interface Login {

    void login(String name, String password);
 }

public class LoginImpl implements Login {

    @Audit(handler = LoginHandler.class)
    public void login(String name, String password) {
        System.out.println("login");
    }

}

@Audit is defined as:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {

   Class<? extends Handler> handler();
}

where Handler is:

interface Handler {

    void handle();
}

class LoginHandler implements Handler {

    public void handle() {
        System.out.println("HANDLER CALLED!");
    }
}

and now the real code:

public class LoginFactory {

    private static class AuditInvocationHandler implements InvocationHandler {

        private final Login realLogin;

        public AuditInvocationHandler(Login realLogin) {
            this.realLogin = realLogin;
        }

        public Object invoke(Object proxy, Method method, Object[] args) 
                      throws Throwable {
            Method realMethod = realLogin.getClass().getMethod(
                                        method.getName(), 
                                        method.getParameterTypes());
            Audit audit = realMethod.getAnnotation(Audit.class);

            if (audit != null) {
                audit.handler().newInstance().handle();
            }

            return method.invoke(realLogin, args);
        }
    }

    public static Login createLogin() {
        return (Login) Proxy.newProxyInstance(
                LoginFactory.class.getClassLoader(),
                new Class[]{Login.class},
                new AuditInvocationHandler(new LoginImpl()));
    }
}

@Test:

    Login login = LoginFactory.createLogin();
    login.login("user", "secret");
    login.logout();

output:

HANDLER CALLED!
login
logout

这篇关于Java:基于注释的代码注入的简单技术?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆