Как Spring / Hibernate Access частные пользователи? - PullRequest
8 голосов
/ 08 ноября 2010

Как вы знаете, Spring может вводить значения в частные переменные экземпляра, а Hibernate может обращаться к закрытым переменным постоянных классов. Однако я даже не могу вызывать защищенные методы класса через рефлексию! Как Spring и Hibernate могут так грубо нарушать безопасность? И что более важно, как мне это сделать? : D

Ответы [ 3 ]

8 голосов
/ 08 ноября 2010

При работе без менеджера безопасности с запретом вы можете получить экземпляр соответствующего метода или отражения через поле и вызвать на нем setAccessible () .

Используя менеджер безопасности Java, вы, конечно, можете отключитьчто, написав собственную политику.

3 голосов
/ 29 октября 2011

Вы можете установить приватную переменную другого объекта через отражение.Вот пример того, как это сделать.Рассмотрим следующий объект с закрытой переменной:

public class MyBean {
    private String message;
}

Обычно поле message обычно не доступно извне MyBean , однако SnoopyClass можно установить и получить его значение.Я написал два статических метода: setValue, который может установить значение в закрытое поле с именем fieldName объекта bean и метод getValue, который можетполучить значение закрытой переменной fieldName из объекта bean .

Метод main просто демонстрирует его использование путем создания объектаКласс MyBean, установка переменной message и ее получение.Я на самом деле тестировал этот код как отдельное приложение, и оно работает.

import java.lang.reflect.Field;

public class SnoopyClass {

    private static void setValue(Object bean, String fieldName, Object value)
            throws IllegalArgumentException, IllegalAccessException, 
            SecurityException, NoSuchFieldException {
        Field privateVar = bean.getClass().getDeclaredField(fieldName);
        privateVar.setAccessible(true);
        privateVar.set(bean, value);
    }

    private static Object getValue(Object bean, String fieldName) 
            throws IllegalArgumentException, IllegalAccessException,
            SecurityException, NoSuchFieldException {
        Field privateVar = bean.getClass().getDeclaredField(fieldName);
        privateVar.setAccessible(true);
        return privateVar.get(bean);
    }

    public static void main(String[] argv) 
            throws IllegalArgumentException, SecurityException,
            IllegalAccessException, NoSuchFieldException {
         MyBean instance = new MyBean();
         setValue(instance, "message", "Shht! Don't tell anyone!");
         System.out.println("The message is '" + getValue(instance, "message"));
    }

}

Реализация использует метод getDeclaredField в классе Object, потому что этот метод может искать все поля, даже частные.Напротив, getField может получить доступ только к публичным участникам.Следующим шагом является вызов setAccessible в поле, чтобы разрешить его чтение и запись.Последний шаг - это просто использование методов get и set, предоставляемых классом java.lang.reflect.Field.

Этот вид манипуляции разрешен только в том случае, если менеджер безопасности позволяет это.По умолчанию Java не устанавливает никакого менеджера безопасности, поэтому в автономной программе, которую вы запускаете через IDE или командную строку, у вас не возникнет проблем с использованием этой техники.Я также пробовал в приложении Spring под Tomcat, и оно все еще работает.

Основное приложение, по крайней мере для меня, может устанавливать частные переменные в моих модульных тестах, особенно для Spring Beans,без загрязнения интерфейса ненужными установщиками.

1 голос
/ 08 ноября 2010

Hibernate может получить доступ к закрытым членам через механизм настройки доступа на уровне «поля». Из документации, раздел 5.1.11

"Атрибут доступа позволяет вам контролировать, как Hibernate обращается к свойству во время выполнения. По умолчанию Hibernate будет вызывать свойство get / set pair. Если вы укажете access =" field ", Hibernate пропустит пару get / set и получить доступ к полю напрямую, используя отражение. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...