복붙노트

[SPRING] 봄 / 최대 절전 모드로 사립 멤버에 액세스 할 수 있습니까?

SPRING

봄 / 최대 절전 모드로 사립 멤버에 액세스 할 수 있습니까?

알다시피, Spring은 private 인스턴스 변수에 값을 삽입 할 수 있고, Hibernate는 영속 클래스의 private 변수에 접근 할 수있다. 그러나, 나는 반성을 통해 클래스의 보호 된 메소드를 호출 할조차 수 없다! Spring과 Hibernate는 어떻게 그런 보안을 뻔뻔스럽게 위반할 수 있습니까? 그리고 더 중요하게, 나는 그것을 어떻게 하는가? :디

해결법

  1. ==============================

    1.금지 된 보안 관리자없이 실행하면 해당 메서드 나 필드 물마루 리플렉션 인스턴스를 가져 와서 setAccessible ()을 호출 할 수 있습니다.

    금지 된 보안 관리자없이 실행하면 해당 메서드 나 필드 물마루 리플렉션 인스턴스를 가져 와서 setAccessible ()을 호출 할 수 있습니다.

    Java 보안 관리자를 사용하면 물론 사용자 정의 정책을 작성하여이를 비활성화 할 수 있습니다.

  2. ==============================

    2.리플렉션을 통해 다른 객체의 변수를 private로 설정할 수 있습니다. 그것을하는 방법에 대한 예제입니다. private 변수를 사용하여 다음 객체를 고려하십시오.

    리플렉션을 통해 다른 객체의 변수를 private로 설정할 수 있습니다. 그것을하는 방법에 대한 예제입니다. private 변수를 사용하여 다음 객체를 고려하십시오.

    public class MyBean {
        private String message;
    }
    

    일반적으로 메시지 필드는 MyBean 외부에서 액세스 할 수 없지만 SnoopyClass는 값을 설정하고 가져올 수 있습니다. 필자는 두 가지 정적 메소드를 작성했습니다. setValue는 Object bean의 fieldName이라는 private 필드에 값을 설정할 수 있고, getValue 메소드는 Object bean에서 fieldName이라는 private 변수의 값을 가져올 수 있습니다.

    main 메소드는 MyBean 클래스의 Object를 생성하고, 메시지 변수를 설정하고 그것을 가져 와서 사용법을 보여줍니다. 실제로이 코드를 독립 실행 형 응용 프로그램으로 테스트 한 결과 작동합니다.

    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"));
        }
    
    }
    

    구현은 Object 클래스에서 getDeclaredField 메서드를 사용합니다.이 메서드는 모든 필드 (개인 필드도 포함)를 찾을 수 있기 때문입니다. 반대로 getField는 public 멤버에만 액세스 할 수 있습니다. 다음 단계는 필드에서 setAccessible을 호출하여 읽기 및 쓰기를 허용하는 것입니다. 마지막 단계는 java.lang.reflect.Field 클래스에서 제공하는 get 및 set 메소드를 사용하는 것입니다.

    이러한 종류의 조작은 보안 관리자가 허용하는 경우에만 허용됩니다. 기본적으로 Java는 보안 관리자를 설치하지 않으므로 IDE 또는 명령 줄을 통해 실행하는 독립 실행 형 프로그램에서이 기술을 사용하는 데 문제가 없습니다. Tomcat의 Spring Application에서도 시도해 보았지만 아직 작동 중이다.

    적어도 나를위한 기본 애플리케이션은 불필요한 setter와의 인터페이스를 오염시키지 않으면 서, 특히 Spring Beans 용 유닛 테스트에서 개인 변수를 설정할 수있게되었습니다.

  3. ==============================

    3.Hibernate는 '필드'레벨 액세스 구성 메커니즘을 통해 전용 멤버에 액세스 할 수 있습니다. 문서에서 5.1.11 절

    Hibernate는 '필드'레벨 액세스 구성 메커니즘을 통해 전용 멤버에 액세스 할 수 있습니다. 문서에서 5.1.11 절

    "access 속성은 당신이 런타임에 Hibernate가 그 속성에 접근하는 방법을 제어 할 수있게 해준다. 기본적으로 Hibernate는 속성 get / set 쌍을 호출 할 것이다. 만약 access ="field "를 지정하면, Hibernate는 get / set 쌍을 건너 뛰고 필드에 접근 할 것이다 직접 반사를 사용합니다. "

  4. from https://stackoverflow.com/questions/4127365/how-can-spring-hibernate-access-private-members by cc-by-sa and MIT license