Java Learning - Preliminary understanding of reflection and dynamic proxies
"This is a summary of video material and video compilation for Chuanzhuan Big Data Course"
1 Reflection
The attributes, methods, constructors, etc. in a class object can be retrieved by reflection
1 package thread.reflect;
2
3 import org.junit.Before;
4 import org.junit.Test;
5
6 import java.lang.reflect.Constructor;
7 import java.lang.reflect.Field;
8 import java.lang.reflect.Method;
9
10 public class MyReflect {
11
12 public String className = null;
13 @SuppressWarnings("rawtypes")
14 public Class personClass = null;
15 /**
16 * Reflect Person Class
17 * @throws Exception
18 */
19 @Before
20 public void init() throws Exception {
21 className = "thread.reflect.Person";
22 personClass = Class.forName(className);
23 }
24 /**
25 *Get a class file object
26 */
27 @Test
28 public void getClassName() throws Exception {
29 System.out.println(personClass);
30 }
31 /**
32 *Another way to get a class file object
33 */
34 @Test
35 public void getClassName2() throws Exception {
36 System.out.println(Person.class);
37 }
38 /**
39 *Create an instance object represented by a class file, and the underlying layer invokes the construction of empty parameters
40 */
41 @Test
42 public void getNewInstance() throws Exception {
43 System.out.println(personClass.newInstance());
44 }
45 /**
46 *Get a non-private constructor
47 */
48 @SuppressWarnings({ "rawtypes", "unchecked" })
49 @Test
50 public void getPublicConstructor() throws Exception {
51 Constructor constructor = personClass.getConstructor(Long.class,String.class);
52 Person person = (Person)constructor.newInstance(100L,"zhangsan");
53 System.out.println(person.getId());
54 System.out.println(person.getName());
55 }
56 /**
57 *Get Private Constructors
58 */
59 @SuppressWarnings({ "rawtypes", "unchecked" })
60 @Test
61 public void getPrivateConstructor() throws Exception {
62 Constructor con = personClass.getDeclaredConstructor(String.class);
63 con.setAccessible(true);//Forced Cancellation Java Permission Detection
64 Person person2 = (Person)con.newInstance("zhangsan");
65 System.out.println("**"+person2.getName());
66 }
67 /**
68 *Accessing non-private member variables
69 */
70 @SuppressWarnings({ "rawtypes", "unchecked" })
71 @Test
72 public void getNotPrivateField() throws Exception {
73 Constructor constructor = personClass.getConstructor(Long.class,String.class);
74 Object obj = constructor.newInstance(100L,"zhangsan");
75
76 Field field = personClass.getField("name");
77 field.set(obj, "lisi");
78 System.out.println(field.get(obj));
79 }
80 /**
81 *Accessing private member variables
82 */
83 @SuppressWarnings({ "rawtypes", "unchecked" })
84 @Test
85 public void getPrivateField() throws Exception {
86 Constructor constructor = personClass.getConstructor(Long.class);
87 Object obj = constructor.newInstance(100L);
88
89 Field field2 = personClass.getDeclaredField("id");
90 field2.setAccessible(true);//Forced Cancellation Java Permission Detection
91 field2.set(obj,10000L);
92 System.out.println(field2.get(obj));
93 }
94 /**
95 *Get non-private member functions
96 */
97 @SuppressWarnings({ "unchecked" })
98 @Test
99 public void getNotPrivateMethod() throws Exception {
100 System.out.println(personClass.getMethod("toString"));
101
102 Object obj = personClass.newInstance();//Constructor to get empty parameters
103 Method toStringMethod = personClass.getMethod("toString");
104 Object object = toStringMethod.invoke(obj);
105 System.out.println(object);
106 }
107 /**
108 *Get private member functions
109 */
110 @SuppressWarnings("unchecked")
111 @Test
112 public void getPrivateMethod() throws Exception {
113 Object obj = personClass.newInstance();//Constructor to get empty parameters
114 Method method = personClass.getDeclaredMethod("getSomeThing");
115 method.setAccessible(true);
116 Object value = method.invoke(obj);
117 System.out.println(value);
118
119 }
120 /**
121 *
122 */
123 @Test
124 public void otherMethod() throws Exception {
125 //Currently loading this class The class loader object for the file
126 System.out.println(personClass.getClassLoader());
127 //Get all interfaces implemented by a class
128 Class[] interfaces = personClass.getInterfaces();
129 for (Class class1 : interfaces) {
130 System.out.println(class1);
131 }
132 //Reflects the direct parent of the current class
133 System.out.println(personClass.getGenericSuperclass());
134 /**
135 * getResourceAsStream This method obtains an input stream that is associated with the file represented by name.
136 */
137 //path No'/'The default at the beginning is to pull resources from the package in which this class resides to'/'Start with ClassPath Get under the root.It just passes through path Construct an absolute path, ultimately by ClassLoader Get resources.
138 System.out.println(personClass.getResourceAsStream("/log4j.properties"));
139 System.out.println(personClass.getResourceAsStream("log4j.properties"));
140
141 //Judge Current Class Is the object representation an array
142 System.out.println(personClass.isArray());
143 System.out.println(new String[3].getClass().isArray());
144
145 //Judge Current Class Is the object representation an enumeration class
146 System.out.println(personClass.isEnum());
147 System.out.println(Class.forName("thread.reflect.City").isEnum());
148
149 //Judge Current Class Is object representation an interface
150 System.out.println(personClass.isInterface());
151 System.out.println(Class.forName("thread.reflect.MyInterface").isInterface());
152
153
154 }
155
156 }
MyReflect
Use reflection for socket calls
Business Interface
1 package thread.reflect.socket;
2
3 public interface Business {
4 int getPrice(String goods);
5 }
Business implementation
1 package thread.reflect.socket;
2
3 public class BusinessImpl implements Business {
4 @Override
5 public int getPrice(String good) {
6 return good.equals("clothes")?10:20;
7 }
8 }
Processing class for server-side socket s
1 package thread.reflect.socket;
2
3 import java.io.*;
4 import java.lang.reflect.Method;
5 import java.net.Socket;
6
7 public class ServerTask implements Runnable{
8 private Socket socket;
9 public ServerTask(Socket socket){
10 this.socket = socket;
11 }
12
13 @Override
14 public void run() {
15 InputStream in;
16 OutputStream out;
17 try {
18 in = socket.getInputStream();
19 out = socket.getOutputStream();
20
21 BufferedReader br = new BufferedReader(new InputStreamReader(in));
22 String request = br.readLine();
23 String[] split = request.split(":");
24 String className = split[0];
25 String methodName = split[1];
26 String methodParam= split[2];
27
28 Class<?> forName = Class.forName(className);
29 System.out.println("calling class: " + forName);
30 Object newInstance = forName.newInstance();
31 Method method = forName.getMethod(methodName,String.class);
32 System.out.println("calling method: " + method);
33 Object invoke = method.invoke(newInstance, methodParam);
34 int value = Integer.parseInt(invoke.toString());
35 System.out.println("results: " + value);
36
37
38 PrintWriter pw = new PrintWriter(new BufferedOutputStream(out));
39 pw.println(value);
40 pw.flush();
41
42 br.close();
43 pw.close();
44 socket.close();
45
46 } catch (Exception e) {
47
48 e.printStackTrace();
49 }
50
51 }
52
53 }
Server-side Run Class
1 package thread.reflect.socket;
2
3 import java.net.InetSocketAddress;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6
7 public class Server {
8 public static void main(String[] args) throws Exception {
9 ServerSocket server = new ServerSocket();
10 server.bind(new InetSocketAddress("localhost",9898));
11 while(true){
12 Socket socket = server.accept();
13 new Thread(new ServerTask(socket)).start();
14 }
15 }
16 }
Client Run Class
1 package thread.reflect.socket;
2
3 import java.io.*;
4 import java.net.Socket;
5
6 public class Client {
7 public static void main(String[] args) throws Exception {
8 Socket socket = new Socket("localhost", 9898);
9 OutputStream out = socket.getOutputStream();
10 InputStream in = socket.getInputStream();
11
12 PrintWriter pw = new PrintWriter(new BufferedOutputStream(out));
13 pw.println("thread.reflect.socket.BusinessImpl:getPrice:clothes");
14 pw.flush();
15
16 BufferedReader br = new BufferedReader(new InputStreamReader(in));
17 String readLine = br.readLine();
18
19 System.out.println("client get result: " + readLine);
20
21 socket.close();
22
23
24
25 }
26 }
2 Dynamic Proxy
In the previous code invocation phase, we implemented the business by invoking service with action.
Because the business previously implemented in the service may not be able to meet the requirements of the first customer, we need to modify the methods in the service, but the methods of the service are not only used in our module, but also called in other modules. When other modules call, the existing service methods can already be usedIt's enough to meet business needs, so we can't just modify the service for our business, causing other modules to influence it.
What about that?
The method implementation in our service can be extended by dynamic proxy to add more business to the original method instead of actually modifying the method in the service, which is called dynamic proxy.
Dynamic Agent: On the basis of not modifying the original business, re-expand to achieve new business based on the original business method.
For example:
1. Old Business
Buyer calls action to purchase clothes. The price of clothes in the database is 50 yuan. The purchasing process is a simple call.
2. New Business
The coupon can be used at the original price, but this function has not been implemented before. We proxy the original interface method through the proxy class, and modify the return value on the basis of this method.
Agent implementation process:
1. Write proxy classes and proxy methods to implement proxy Proxy.newProxyInstance in proxy methods
2. The required parameters in the proxy are: the class loader soneObjectclass.getClassLoader() of the class being proxied, all the implementation interfaces of the class being proxied new Class[] {Interface.class}, and the handle method new InvocationHandler()
3. Replicate the invoke method in the handle method. The input of the invoke method has three parameters: Object proxy (proxy class object), Method (proxy class method), Object[] args (incoming parameter of proxy class method). In this method, we can customize the development of new business.
4. Obtain proxy classes and forcefully convert to proxy interfaces
5. Finally, as if we were not proxied, we could call an interface's approved method. After the method was called, the method name and parameter list would be passed into the invoke method of the proxy class to do the logical process of the new business.
IBoss Business Interface Definition Class
1 package thread.proxy.bossProxy;
2
3 public interface IBoss {
4 int sales(String size);
5
6 String giveBack(String size);
7 }
Boss Business Interface Implementation Class
1 package thread.proxy.bossProxy;
2
3 public class Boss implements IBoss{
4
5 @Override
6 public int sales(String size) {
7 System.err.println("Tmall Xiaoqiang flagship store clothes A Size:"+size);
8 //The price of this dress, read from the database
9 return 50;
10 }
11
12 @Override
13 public String giveBack(String size) {
14 return "Return";
15 }
16 }
Boss Business Call Class
1 package thread.proxy.bossProxy;
2
3 import org.junit.Test;
4
5 public class SalesAction {
6 /**
7 * Call method directly without proxy
8 * Method specifies what business can only be invoked, what return value can be specified, and what return value can only be output
9 */
10 @Test
11 public void saleByBossSelf() throws Exception {
12 IBoss boss = new Boss();
13 System.out.println("The boss owns himself!");
14 int money = boss.sales("xxl");// The boss sells his own clothes and doesn't need customer service. As a result, he doesn't have a chat record
15 System.out.println("Clothing prices:" + money);
16 }
17 }
Agent Boss Business Implementation Class
1 package thread.proxy.bossProxy;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7 public class ProxyBoss {
8
9 @SuppressWarnings("unchecked")
10 public static <T> T getProxy(final int discountCoupon,final Class<?> interfaceClass, final Class<?> implementsClass)
11 throws Exception {
12 return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
13 new Class[] { interfaceClass }, new InvocationHandler() {
14 public Object invoke(Object proxy, Method method,
15 Object[] args) throws Throwable {
16 Integer returnValue = (Integer) method.invoke(
17 implementsClass.newInstance(), args);// Value returned after calling the original object
18 return returnValue - discountCoupon;
19 }
20 });
21 }
22 }
Proxy Boss Business Call Class
1 package thread.proxy.bossProxy;
2
3 import org.junit.Test;
4
5 public class ProxySalesAction {
6
7 @Test
8 public void saleByProxy() throws Exception {
9 IBoss boss = ProxyBoss.getProxy(10,IBoss.class,Boss.class);// Instantiate the proxy's methods into interfaces
10 System.out.println("Agent business!");
11 int money = boss.sales("xxl");// Call the interface's methods, but the way they are actually called is unchanged
12 System.out.println("Clothing prices:" + money);
13 }
14
15 }