什么是代理
从字面意思来说,代理就是代替处理的意思。
从程序层面来说,代理就是代替某个程序,处理某个事情。
静态代理
场景1: 小明需要买基金。
public class Main {
public static void main(String[] args) {
Person xiaoming= new XiaoMing();
boolean isSuccess = xiaoming.buy();//小明去买基金
System.out.println("结果"+(isSuccess?"基金大涨":"被割韭菜"));
}
}
interface Person{
boolean buy();
}
class XiaoMing implements Person{
@Override
public boolean buy() {
System.out.println("我是小明,我要买基金");
return false;
}
}
运行结果
我是小明,我要买基金
结果被割韭菜
场景2: 小明刚买了不久的基金,连跌几天,被割了韭菜,这时候小明找到了一个基金经理,让基金经理帮自己管理基金。
我们新增一个 基金经理的类,并传入一个被代理的人
public class Main {
public static void main(String[] args) {
Person fundManager = new FundManager(new XiaoMing()) ;//小明被基金经理代理了
boolean isSuccess = fundManager.buy();//基金经理去买基金
System.out.println("结果"+(isSuccess?"基金大涨":"被割韭菜"));
}
}
interface Person{
boolean buy();
}
class XiaoMing implements Person{
@Override
public boolean buy() {
System.out.println("我是小明,我要买基金");
return false;
}
}
class FundManager implements Person{
Person person;
FundManager(Person person){
this.person = person;
}
@Override
public boolean buy() {
person.buy();
System.out.println("我是基金经理,我帮我的用户赚钱");
return true;
}
}
运行结果
我是小明,我要买基金
我是基金经理,我帮我的用户赚钱
结果基金大涨
场景3: 小明已经通过基金经理赚了不少钱,他需要卖出一部分,并且开始进行基金定投。
package cn.enncy.scs;
public class Main {
public static void main(String[] args) {
Person fundManager = new FundManager(new XiaoMing()) ;
fundManager.buy();
fundManager.sell();
fundManager.autoInvestment();
}
}
interface Person{
boolean buy();
boolean sell();
boolean autoInvestment();
}
class XiaoMing implements Person{
@Override
public boolean buy() {
System.out.println("我是小明,我要买基金");
return false;
}
@Override
public boolean sell() {
System.out.println("我是小明,我要出售基金");
return false;
}
@Override
public boolean autoInvestment() {
System.out.println("我是小明,我要定投基金");
return false;
}
}
class FundManager implements Person{
Person person;
FundManager(Person person){
this.person = person;
}
@Override
public boolean buy() {
person.buy();
System.out.println("我是基金经理,我帮我的用户赚钱");
return true;
}
@Override
public boolean sell() {
return person.sell();
}
@Override
public boolean autoInvestment() {
return person.autoInvestment();
}
}
结果
我是小明,我要买基金
我是基金经理,我帮我的用户赚钱
我是小明,我要出售基金
我是小明,我要定投基金
我们可以看到,其实定投
和出售
,根本不需要经过基金经理进行代理,自己进行这个操作就行了,所以代码非常冗余,如果不经过基金经理又会被割韭菜。
那要怎么实现,当买基金的时候让基金经理代理,不需要买基金的时候,其他操作自己执行
?
这时候,动态代理
的优势就体现出来了
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
PersonProxy personProxy = new PersonProxy(new XiaoMing());
Person fundManager = personProxy.createProxy();
fundManager.buy();
fundManager.sell();
fundManager.autoInvestment();
}
}
interface Person{
boolean buy();
boolean sell();
boolean autoInvestment();
}
class XiaoMing implements Person{
@Override
public boolean buy() {
System.out.println("我是小明,我要买基金");
return false;
}
@Override
public boolean sell() {
System.out.println("我是小明,我要出售基金");
return false;
}
@Override
public boolean autoInvestment() {
System.out.println("我是小明,我要定投基金");
return false;
}
}
class PersonProxy implements InvocationHandler {
Object target;
PersonProxy(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("方法"+method.getName()+"已经被我代理");
if("buy".equals(method.getName())){
method.invoke(target, args);
System.out.println("我是代理,我将帮你买基金");
}
return true;
}
public <T> T createProxy(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}
结果
方法buy已经被我代理
我是小明,我要买基金
我是代理,我将帮你买基金
方法sell已经被我代理
方法autoInvestment已经被我代理
-
target
: 被代理的对象
-
InvocationHandler
: jdk 动态代理类
-
invoke
: 由jdk动态代理的方法,
-
proxy
: jdk 代理类
-
method
: 当前被代理类的方法
-
args
当前被代理类的方法参数
-
Proxy.newProxyInstance
: 代理类的实例化方法
-
target.getClass().getClassLoader()
: 目标类的 ClassLoader
-
target.getClass().getInterfaces()
: 目标类的 interfaces
-
this
: 代理类对象
动态代理-代理接口
想要实例化接口,但是又不创建实例类的骚操作,具体实现方法完全通过动态代理自由实现。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
Person personProxy = PersonProxy.createProxy(Person.class);
personProxy.say();
}
}
interface Person{
void say();
}
class PersonProxy implements InvocationHandler {
Class target;
PersonProxy(Class target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我就是"+method.getName()+"函数的方法体!");
return null;
}
public static <T> T createProxy(Class clazz){
return (T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class[]{clazz}, new PersonProxy(clazz));
}
}
结果
我就是say函数的方法体!
是不是非常 amazing !!!
根本没有任何的实例类!但是同样可以调用方法!可以调侃的说接口自己实现了自己
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)