Java: Простая техника для основанной на аннотации инжекции кода?

Tom корректен в описании точно, что + делает оператор. Это создает временный файл StringBuilder, добавляет части и заканчивается с toString().

Однако все ответы до сих пор игнорируют эффекты оптимизации времени выполнения HotSpot. А именно, эти временные операции распознаны как общий шаблон и заменяются более эффективным машинным кодом во времени выполнения.

@marcio: Вы создали микросравнительный тест ; с современной JVM это не допустимый способ представить код.

причина, оптимизация времени выполнения имеет значение, состоит в том, что многие из этих различий в коде - даже включая создание объекта - полностью отличаются, как только HotSpot начинается. Единственный способ знать наверняка представляет Ваш код на месте .

Наконец, все эти методы на самом деле невероятно быстры. Это могло бы быть случаем преждевременной оптимизации. Если у Вас есть код, который конкатенирует, представляет много в виде строки, способ получить максимальную скорость, вероятно, не имеет никакого отношения, какие операторы Вы выбираете и вместо этого алгоритм, который Вы используете!

5
задан Robert Wilson 3 July 2009 в 13:30
поделиться

3 ответа

Использовать отражение легко, просто аннотируйте метод с помощью @Audit, точно так же, как тестовые программы в 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 определяется как:

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

   Class<? extends Handler> handler();
}

, где Handler:

interface Handler {

    void handle();
}

class LoginHandler implements Handler {

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

, а теперь реальный код:

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();

вывод:

HANDLER CALLED!
login
logout
16
ответ дан 18 December 2019 в 07:10
поделиться

Готово - используйте Spring или Guice .

Самостоятельное катание имеет смысл, если вы хотите знать, как работают колеса , или если вы думаете, что можете сделать что-то гораздо более легкое. Просто убедитесь, что оба верны, прежде чем браться за это.

5
ответ дан 18 December 2019 в 07:10
поделиться

Взгляните на методы перехвата в Guice: http://code.google.com/p/google-guice/wiki/AOP

Аналогичный подход должен работать с любая структура АОП.

1
ответ дан 18 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: