This is the 18th day of my participation in the August Challenge


1. The MySql proxy

Back-end developers can’t avoid dealing with databases, and MySQL is a very popular relational database these days. Suppose you have an SQL statement executor that supports two operations: query and write.

interface SqlExecutor {

	/ / read operation
	Object query(String sql);

	/ / write operations
	int update(String sql);
}

class MySqlExecutor implements SqlExecutor{... }Copy the code

Now there is a new requirement to output the SQL statements executed by SqlExecutor to the console for debugging purposes. What are you going to do? Do you modify MySqlExecutor directly? This does not comply with the open closed principle.

The correct approach would be to create a proxy classLogProxyTo complete the output of SQL statements.

public class LogProxy implements SqlExecutor {
	private SqlExecutor target;
	public LogProxy(SqlExecutor executor) {
		this.target = executor;
	}

	@Override
	public Object query(String sql) {
		System.out.println("Query SQL." + sql);
		return target.query(sql);
	}

	@Override
	public int update(String sql) {
		System.out.println(Modify the SQL: "" + sql);
		returntarget.update(sql); }}Copy the code

Now there is a new requirement that for repeated SQL queries, the query results can be cached and fetched directly from the cache the next time the query is performed. To change againSqlExecutorThe source code? Don’t forget, that doesn’t match the open and close principle and can be enhanced by proxy objects.

class CacheProxy implements SqlExecutor {
	private Map<String, Object> cache = new ConcurrentHashMap<>();
	private SqlExecutor target;

	public CacheProxy(SqlExecutor executor) {
		this.target = executor;
	}

	@Override
	public Object query(String sql) {
		if (cache.containsKey(sql)) {
			System.out.println("Hit cache...");
			return cache.get(sql);
		}
		Object result = target.query(sql);
		cache.put(sql, result);
		return result;
	}

	@Override
	public int update(String sql) {
		System.out.println("Cache invalid...");
		cache.clear();
		returntarget.update(sql); }}Copy the code

This is the proxy mode!

2. Definition of proxy mode

Provide a proxy for other objects to control access to that object.

Proxy pattern generic class diagram

  • Subject: Subject abstraction, implemented by RealSubject and Proxy.
  • RealSubject: The concrete subject, the real executor of the business, is also a proxied object.
  • Proxy: a class that enhances the logic of a RealSubject.

It is up to the scene class to determine which object a proxy class should proide, usually through the constructor to specify the proided object.

3. Advantages of the proxy model

  1. The responsibilities are very clear. The prostee is only responsible for its own business logic, and the things that do not need to be cared about or are not responsible are entrusted to the agent class, in accordance with the principle of single responsibility.
  2. It is so extensible that enhancements can be made by creating a proxy class, and proxy objects can also be proxies for another proxy object to pass on enhancements.
  3. Proxies have more flexibility for enhancements than inheritance.

If you want to make enhancements to a class that are not within the scope of the class itself, you can do so by creating a proxy class.

JDK dynamic proxy

The above example is a normal proxy implementation, which requires the developer to write the proxy class, implement and implement the interface implemented by the proxy class, rewrite all methods, and then forward the method execution to the proxied object, which can be cumbersome if there are many methods to implement. JDK provides dynamic Proxy support, Proxy and InvocationHandler can be used to dynamically generate a Proxy object for the Proxy object, very convenient to use.

Create a new class that implements the InvocationHandler interface and overrides the Invoke method to create a Proxy object with proxy.newProxyInstance ().

JDK dynamic proxy application scenario is very extensive, in many excellent open source framework can see its figure, such as MyBatis through the interface operation database, used JDK dynamic proxy.

Note: JDK dynamic proxy requires classes to implement interfaces!!

5. To summarize

Proxy mode application is very extensive, the most classic example is the Spring AOP technology, it can not modify the source code under the situation of the system to enhance the function, the bottom is through the generation of proxy object to complete, as long as you debug the discovery of the proxy class class name $Proxy0 shows that it is a proxy object. The bottom line is that if you need to enhance a class that doesn’t fall within the scope of the class itself, consider using the proxy pattern.