1. Java의 반사
1. 반사를 통해 클래스의 속성 및 메소드 인스턴스 코드를로드하십시오.
/*** java.lang.class는 반사의 소스입니다* 우리는 클래스를 만들고 (javac.exe)를 컴파일하여 해당 클래스 파일을 생성했습니다. 이 클래스 파일을로드 한 후이 클래스 파일*이 클래스 파일이 메모리에로드 된 후 캐시 영역이있는 런타임 클래스입니다. 이 런타임 클래스는 클래스 인스턴스 * 각 런타임 클래스는 한 번만로드됩니다. StudentExam StudentExam = Clazz.newinstance (); System.err.println (StudentExam); System.out.println (Clazz); // 필드 필드 = clazz.getfield ( "id"); // 속성을 통해 런타임 클래스의 지정된 속성을 호출합니다. 속성은 공개 유형 필드 필드 = clazz.getDeclaredfield ( "id"); // 속성은 비 공개 유형 필드 [] fields = clazz.getDeclaredFields (); // 런타임 클래스 자체의 모든 선언 된 속성을 가져옵니다 (부모 클래스는 수행 할 수 없습니다). 상위 클래스는 Clazz.getFields ()를 사용합니다. for (field field2 : fields) {int i = field2.getModifiers (); 문자열 유형 = modifier.tostring (i); // 필드 속성 시스템의 데이터 유형을 가져옵니다. } field.setAccessible (true); Field.Set (StudentExam, 11); System.err.println (StudentExam.getId ()); // 반사 시간을 통해 런타임 클래스의 지정된 메소드를 호출합니다. 메소드 방법 = clazz.getMethod ( "setid", integer.class); Method.invoke (StudentExam, 123); // 런타임 클래스 메소드의 지정된 메소드를 호출합니다 [] method = clazz.getMethods (); // 모든 런타임 클래스 및 부모 클래스에서 공개적으로 선언 된 모든 메소드를 가져옵니다 [] method2 = clazz.getDeclaredMethods (); // 런타임 클래스 자체에서 (메소드 메소드 : 메소드) {System.out.println (method2.getName ())에 대해 런타임 클래스 자체에서 선언 된 메소드를 가져옵니다. } // * 개체의 getClass () 메소드를 통해 객체의 런타임 클래스를 가져옵니다. 시험 시험 = new Exam (); 클래스 ClazzExam = Exam.GetClass ();2. 클래스 로더
/** * 설명 : 클래스 로더, xx.properties 파일을로드하고 데이터 * @param * @Author XIAZHONGWEI * @DATA 9 월 29 일 : 5:32:56 PM * @return */public void ClassLoader ()는 ioException {// 메소드로드로드 클래스로드 (getclass) (getClass) // 경로는 패키지 아래에 작성됩니다. com // ably // onlineexam // resources // config.properties inputStream instream = loader.getResourceasStream ( "config.properties"); // 메소드 2. 지정된 경로에서 파일을로드 // fileInputStream fileInputStream = 새 fileInputStream (새 파일 ( "config.properties")); 속성 속성 = 새로운 속성 (); 속성 .LOAD (Instream); // properties.load (fileInputStream); 문자열 prop = properties.getProperty ( "도메인"); System.out.println (prop); }3. 동적 프록시
정적 프록시 : 프록시 클래스의 유형과 대상 객체는 컴파일 중에 결정되며 프로그램의 확장에는 도움이되지 않습니다. 동시에, 각 프록시 클래스는 하나의 인터페이스 만 제공 할 수 있으므로 너무 많은 프록시는 필연적으로 프로그램 개발에서 발생합니다.
동적 프록시 : 클라이언트는 프록시 클래스를 통해 다른 객체의 메소드를 호출하고 프로그램이 실행될 때 필요에 따라 대상 클래스의 프록시 객체를 동적으로 생성합니다.
에이전트 설계 패턴의 원리 :
프록시를 사용하여 객체를 감싸고 원래 객체를 프록시 객체로 교체하십시오. 원래 객체에 대한 모든 호출은 프록시 객체가 메소드가
패키지 com.test.junit; import java.lang.reflect.invocationHandler; import java.lang.reflect.method; import java.lang.reflect.proxy; public class proxytest {public static void main (String [] args) {realSubject realSubject = new RealSubject (); MyInVoctionHandler MyInVocationHandler = New MyInvocationHandler (); Object 객체 = myinVocationHandler.bind (realSubject); 주제 주제 = (주제) 대상; 대상 (); }} // 동적 프록시 인터페이스의 사용 {void action ();} // class realSubject impless and {@override public void action () {system.out.println ( "나는 프록시 클래스입니다 ..."); }} class myInvocationHandler는 invocationHandler를 구현합니다 {Object Object; // 인터페이스의 프록시 클래스의 객체의 선언/ ** * 설명 : ① 프록시 객체를 인스턴스화합니다. = 객체; return proxy.newproxyInstance (object.getClass (). getClassLoader (), object.getClass (). getInterfaces (), this); } / ** * 프록시 클래스의 객체를 통해 다시 작성된 메소드에 대한 호출이 시작되면 다음 호출 메소드로 호출로 변환됩니다 * / @override public object invoke (개체 프록시, 메소드 메소드, 오브젝트 [] args) 던질 수있는 {object returnObject = method.invoke (object, args); return returnObject; }}4. 동적 프록시 및 AOP
예 1.
패키지 com.atguigu.spring.aop; 공개 인터페이스 산술 계산기 {int add (int i, int j); int sub (int i, int j); int mul (int i, int j); int div (int i, int j);} 패키지 com.atguigu.spring.aop; org.springframework.stereotyp.component import; @component ( "ArithmeticCalculator") 공개 클래스 ArithmeticCalculatorimpl은 ArithmeticCalculator {@override public int add (int i, int j) {int result = i + j; 반환 결과; } @override public int sub (int i, int j) {int result = i -j; 반환 결과; } @override public int mul (int i, int j) {int result = i * j; 반환 결과; } @override public int div (int i, int j) {int result = i / j; 반환 결과; }} 패키지 com.atguigu.spring.aop; 공개 클래스 ArithmeticCalculatorLoggingimpl은 ArithmeticCalculator {@override public int add (int i, int j) {System.out.println ( "메소드 애드는 [" + i + "," + j + "]로 시작합니다. int result = i + j; System.out.println ( "메소드 추가는" + 결과로 끝); 반환 결과; } @override public int sub (int i, int j) {system.out.println ( "메소드 하위는 [" + i + "," + j + "]로 시작합니다. int result = i -j; System.out.println ( "메소드 서브는" + 결과로 끝); 반환 결과; } @override public int mul (int i, int j) {system.out.println ( "메소드 mul은 [" + i + "," + j + "]로 시작합니다. int result = i * j; System.out.println ( "MUL 메소드 MUL은 [" + i + "," + j + "]로 시작합니다. int result = i * j; System.out.println ( "메소드 MUL은" + result로 끝); 반환 결과; } @override public int div (int i, int j) {system.out.println ( "메소드 div는 [" + i + "," + j + "]로 시작합니다. int result = i / j; System.out.println ( "메소드 div는" + result로 끝냅니다); 반환 결과; }} 패키지 com.atguigu.spring.aop; import java.lang.reflect.invocationHandler; import java.lang.reflect.method; import java.lang.reflect.proxy; import java.util.arrays; 공개 클래스 ArithmeticCalculatorLoggingProxy {// 프록시 프라이버시 arriathmeticCalculator 대상이 될 객체; Public ArithmeticCalculatorLoggingProxy (ArithmeticCalculator Target) {super (); this.target = 대상; } // 프록시 객체를 반환 공개 arriathmeticCalculator getLoggingProxy () {ArithmeticCalculator proxy = null; // 프록시 객체의 클래스 로더가 클래스 로더로드를로드 할 책임이있는 어떤 클래스 로더 = target.getClass (). getClassLoader (); // 프록시 객체의 유형, 즉 어떤 메소드가 있습니다. class [] interfaces = new Class [] {arithmeticeCalculator.class}; // 프록시 오브젝트의 메소드를 호출 할 때 다음 코드를 실행할 때 revocationHandler h = new invocationHandler () { /*** 프록시 : 프록시 객체. 이 객체는 일반적으로 사용되지 않습니다* 방법 :* args : 호출 메소드에서 전달되는 매개 변수*/ @override public 객체 호출 (개체 프록시, 메소드 메소드, Object [] args) 던지기 가능 {// 프록시 객체의 메소드는 메소드 내부에서 직접 호출되지 않습니다. proxy.toString ()은 데드 루프가 invoke method string methodname = method.getName ()을 호출하게됩니다. // log system.out.println을 인쇄합니다 ( "[이전]" + methodname + "메소드는" + arrays.aslist (args)로 시작합니다); // 대상 메소드 호출 객체 result = null; try {// pre-be-aitification result = method.invoke (target, args); // 반환 알림, 메소드의 리턴 값} catch (nullPointerException e) {e.printstacktrace (); // 예외 알림은 메소드의 예외} // post-notification에 액세스 할 수 있습니다. 메소드는 예외가있을 수 있으므로 메소드의 반환 값에 액세스 할 수 없습니다. 반환 결과; }}; /*** 로더 : 프록시 객체에서 사용하는 클래스 로더. * 인터페이스 : 프록시 객체의 유형을 지정하십시오. 즉, 프록시 프록시 객체에서 어떤 방법을 찾을 수 있는지. * H : 프록시 객체의 메소드를 호출 할 때 어떻게 응답해야합니까? 실제로, 호출 방법을 호출하는 방법을 호출하는 것입니다*/ proxy = (ArithmeticCalculator) proxy.newproxyinstance (로더, 인터페이스, h); 리턴 프록시; }} 패키지 com.atguigu.spring.aop; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class main {public static void main (String [] args) {// arithmeticCalculator ArithmeticCalculator = new ArithmeticCalculatorimpl (); ArithmeticCalculator ArithmeticCalculator = New ArithmeticCalculatorLoggingImpl (); ArithmeticCalculator = New ArithmeticCalculatorLoggingProxy (ArithmeticCalculator) .getLoggingProxy (); int result = ArithmeticCalculator.add (11, 12); System.out.println ( "결과 :" + 결과); 결과 = ArithmeticCalculator.div (21, 3); System.out.println ( "결과 :" + 결과); }}예 2.
패키지 com.test.junit; import java.lang.reflect.invocationHandler; import java.lang.reflect.method; import java.lang.reflect.proxy; public class proxytest {public static void main (String [] args) {realSubject realSubject = new RealSubject (); MyInVoctionHandler MyInVocationHandler = New MyInvocationHandler (); Object 객체 = myinVocationHandler.bind (realSubject); 주제 주제 = (주제) 대상; 대상 (); }} // 동적 프록시 인터페이스의 사용 {void action ();} // class realSubject impless and {@override public void action () {system.out.println ( "나는 프록시 클래스입니다 ..."); }} class myInvocationHandler는 invocationHandler를 구현합니다 {Object Object; // 인터페이스의 프록시 클래스의 객체의 선언/ ** * 설명 : ① 프록시 객체를 인스턴스화합니다. = 객체; return proxy.newproxyInstance (object.getClass (). getClassLoader (), object.getClass (). getInterfaces (), this); } / ** * 프록시 클래스의 객체를 통해 다시 작성된 메소드에 대한 호출이 시작되면 다음 호출 메소드로 호출로 변환됩니다 * / @override public object invoke (개체 프록시, 메소드 메소드, 오브젝트 [] args) 던질 수있는 {object returnObject = method.invoke (object, args); return returnObject; }}이 기사를 읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!