The agency mode of design mode (structural type, requires people to do things, so find an agency)

introduce

Application: AOP implementation, interceptor, real estate agency, scalper, matchmaker, decoupling, special people to do special things, things that you don't want to do but have to do.

static proxy

Concept: When a static proxy is used, it is necessary to define an interface or a parent class. The proxied object and the proxy object implement the same interface or inherit the same parent class. In conclusion, before the proxy, everything is known (artificially).
Scenario: Everyone knows that it is difficult for us programmers to find objects, because we are more nerdy and introverted. Zhang San is a programmer who is close to 30 but has not yet found a partner. So his parents began to worry about him. His father planned to help him go on a blind date and asked Zhang San what type of girlfriend he wanted to find. Zhang San said that he liked Bai Fumei with long legs. According to this request, his father found a girl named Sister Feng, and then arranged a date between Zhang San and Sister Feng, after which the two officially became boyfriend and girlfriend. Here, Zhang San is the proxy object, and Zhang San's father is the proxy object.
Code:
1. First describe some characteristics of a person, such as people looking for objects, jobs, shopping and so on.

public interface Person {
    //找对象
    public void findLove();
    //找工作
    public void findJob();
    //买东西
    public void buy();
}

2. At this time, there was a person named Zhang San:

public class ZhangSan implements Person{
    @Override
    public void findLove() {
        System.out.println("我想找一个白富美,大长腿");
    }
    @Override
    public void findJob() {
        System.out.println("我想找一个年薪50W的工作");
    }
    @Override
    public void buy() {
        System.out.println("我想去超市买东西");
    }
}

3. Then there is Zhang San's father:

public class Father implements Person{
    //张三需要告诉父亲他找对象的要求,所以传入自己的引用
    private ZhangSan zhangSan;
    public Father(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }
    @Override
    public void findLove() {
        System.out.println("帮张三去物色,最终找到凤姐并安排他俩约会");
        zhangSan.findLove();
        System.out.println("两人成功的在一起");
    }
    @Override
    public void findJob() {
        zhangSan.findJob();
    }
    @Override
    public void buy() {
        zhangSan.buy();
    }
}

4. His father started to help Zhang San find a partner:

public class ProxyTest {
    public static void main(String[] args) {
        ZhangSan zhangSan=new ZhangSan();

        Father father=new Father(zhangSan);
        father.findLove();
    }

//    运行结果:
//    帮张三去物色,最终找到凤姐并安排他俩约会
//    我想找一个白富美,大长腿
//    两人成功的在一起
}

Summary: Because the proxy object needs to implement the same interface as the target object, there will be many proxy classes (for example: Zhang San's father helps Zhang San find objects, Zhang San's mother helps Zhang San buy things...), there are too many classes. At the same time, once the interface adds methods, both the target object and the proxy object must be maintained.

jdk dynamic proxy

Concept: Using jdk dynamic proxy, the proxy object does not need to implement the interface. The generation of the proxy object is to use the JDK API to dynamically construct the proxy object in memory. In conclusion, before the proxy, everything is unknown. (Automated, Intelligent)
Scenario: Zhang San needs to buy a house, but it is too troublesome to find a house by himself, so he contacted the intermediary, hoping they can help him find a good house. It needs to be understood here that the intermediary helps Zhang San to find a house, but in fact it is the computer that actually searches for the house, and the computer provides a series of house information.
Code:
1. Zhang San and the intermediary are both people, so let's start by describing a person:

public interface Person {
    //找房子
    public void buyHouse();
}

2. There is a person named Zhang San:

public class ZhangSan implements Person {
    @Override
    public void buyHouse() {//张三买房子的要求
        System.out.println("我是张三:我要买一个120平的房子");
    }
}

3. The real estate agent came out:

/**
 * 房产中介
 */
public class HouseAgency implements InvocationHandler{
    //张三需要把找房子的要求告诉中介,所以这里传自己的引用
    private ZhangSan zhangSan;
    public HouseAgency(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是中介:麻烦张三提供房源要求给我");
        method.invoke(zhangSan,args);
        System.out.println("我是中介:帮助张三找到合适房源");
        return null;
    }
}

4. The agent starts to search for listing information on the computer:

/**
 * 开始找房源
 */
public class HouseAgencyTest {
    public static void main(String[] args) {
        //张三出来
        ZhangSan zhangSan=new ZhangSan();
        //张三提供信息
        Class clazz=zhangSan.getClass();
        //房产中介出来
        HouseAgency houseAgency=new HouseAgency(zhangSan);
        //房产中介通过电脑开始搜索房源
        Person result=(Person) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),houseAgency);
        //电脑搜索房源成功
        result.buyHouse();
    }
//    执行结果:
//    我是中介:麻烦张三提供房源要求给我
//    我是张三:我要买一个120平的房子
//    我是中介:帮助张三找到合适房源
}

Summary: The proxy object does not need to implement the interface, but the target object must implement the interface, otherwise dynamic proxy cannot be used.

cglib dynamic proxy

Concept: Using cglib dynamic proxy, the target object does not need to implement the interface. After the jar package of cglib is introduced, the subclass of the target object can be dynamically constructed in the memory, which means that the proxy object inherits the target object. The method of the target object can be called directly. It is worth noting that the target class should not be finalized, otherwise it cannot be inherited by the proxy class.
Scene: Zhang San wanted to find a match, so he contacted a matchmaker, who helped him find a match for a long time, and finally found a match for him. This needs to be understood here. Although the matchmaker is acting for Zhang San to find a target, there will be a real agent behind him to help Zhang San find a target, but this agent is not known to everyone.
Code:
1. First there is Zhang San:

public class ZhangSan {
    public void findLove(){
        System.out.println("肤白貌美,大长腿");
    }
}

2. Then the matchmaker:

public class CglibMeipo implements MethodInterceptor{
    private ZhangSan zhangSan;
    public CglibMeipo(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }
    //真实的代理人帮助张三找对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(zhangSan.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("我是媒婆:麻烦张三给我提供找对象的要求");
        //执行目标对象的方法
        method.invoke(zhangSan, objects);
        System.out.println("我是媒婆:开始找对象");
        return null;
    }
}

3. Start looking for objects:

public class ProxyTest {
    public static void main(String[] args) {
        //张三出来
        ZhangSan zhangSan=new ZhangSan();
        //媒婆出来找到真实代理人
        ZhangSan result=(ZhangSan)new CglibMeipo(zhangSan).getProxyInstance();
        //真实代理人开始找对象
        result.findLove();

//        执行结果:
//        我是媒婆:麻烦张三给我提供找对象的要求
//        肤白貌美,大长腿
//        我是媒婆:开始找对象
    }
}

Summary: The target object does not need to implement the interface. In Spring's AOP programming, if the target object added to the container has an implementation interface, use the JDK proxy. If the target object does not implement the interface, use the cglib proxy.
If you want to understand the underlying implementation of jdk dynamic proxy, please refer to my next microblog: Custom implementation of jdk dynamic proxy source code analysis

Guess you like

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