Decorators, static proxies, dynamic proxies

decorator

introduce:

  • To modify a method of a class, the decorator pattern is used when the class already exists
  • The decorator must implement the same interface as the decorated one
  • The decorator declares a constructor that takes the decorated interface as an input
  • Inside the decorator, the method you want to transform is implemented by yourself, and the method you don't want to transform uses the method of the decorated person
  • When using, there is already a decorated object, new a decorator, and the decorated object is passed in
  • After that, the implementation class of the interface can use the decorated class

Disadvantages: If the class has multiple methods, writing a decorated class will have a lot of code redundancy, and the code is not very elegant

The example is as follows: there is an interface Master and an implementation class Sub, if you want to modify the chi method of this class, write a decoration class SubZs, implement Master, declare a constructor, and the input parameter is Master.

//interface
interface Master{
	public void chi();
	public void pao();
}
//the decorated
class Sub implements Master{

	@Override
	public void chi() {
		System.out.println("chifan");
	}

	@Override
	public void pao() {
		System.out.println("paobu");
	}
	
}
// decorator
class SubZs implements Master{
	private Master m;
	public SubZs(Master m){
		this.m=m;
	}

	@Override
	public void chi() {
		System.out.println("hehe~");
                m.chi();
 }

	@Override
	public void pao() {
		m.pao ();
	}
	
}

Test it out:

public class ZhuangShi {
	public static void main(String[] args) {
		Master m = new Sub();
		Master m2 = new SubZs(m);
		m2.chi ();
	}
}
Result (chi's method is decorated):
hehe~
chifan

static proxy

The code of static proxies and decorators looks the same, but static proxies are not inherently comparable to decorators

They are adapted to different scenarios. The decorator is to decorate the existing class object, and the proxy mode is to find a proxy for the class.

Static proxies are different from dynamic proxies

Dynamic proxy

Dynamic agents are divided into jdk and cglib, which are described below.

  • jdk dynamic proxy

 In the beginning, java provided a dynamic proxy for jdk. The proxy class must implement an interface. The code is as follows:

/**
 declare an interface
 */
interface Master{
	public void chi();
}
/**
The proxy, Sub implements the interface
 */
class Sub implements Master{

	@Override
	public void chi() {
		System.out.println("chifan");
		
	}

}
/**
agent
 */
class proxy{
	Master a;
	public proxy(){};
	public Object getInstance(Master b){
		this.a = b;
		return Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), new InvocationHandler() {
			
			@Override
			public Object invoke(Object arg0, Method arg1, Object[] arg2)
					throws Throwable {
				if(arg1.getName().equals("chi")){
					System.out.println("hehe");
					return null;
				}else{
					return arg1.invoke(a, arg2);
				}
			}
		});
	}
}

Test it out:

public class TestJdkProxy{
	public static void main(String[] args) {
		Master a = (Master)new proxy().getInstance(new Sub());
		to who();
	}

}
turn out:
hehe
  • cglib dynamic proxy

The proxied class does not need to implement the interface, and uses inheritance internally. For details, see the code as follows:

/**
 * The agent
 */
class Sub{
	public void chi(){
		System.out.println("chifan");
	}
}
/**
 agent
 */
class CglibProxy{
	private Sub s;
	public Object getInstance(Sub ss){
		this.s=ss;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(ss.getClass());
		enhancer.setCallback(new MethodInterceptor() {
			
			@Override
			public Object intercept(Object proxy, Method method, Object[] arg2,
					MethodProxy methodProxy) throws Throwable {
				if("chi".equals(method.getName())){
					System.out.println("hehe");
					return null;
				}else{
					return method.invoke(s, arg2);
				}
				
			}
		});
		return enhancer.create();
	}
}

Test it out:

public class TestCglibProxy {
	public static void main(String[] args) {
		Sub subProxy = (Sub)new CglibProxy().getInstance(new Sub());
		subProxy.chi();
	}

}
result:
hehe












Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325881155&siteId=291194637