静态代理和动态代理
静态代理
通过一个代理类实现在不修改原先的代码情况下对功能进行增添。
IUserService.java:
package com.sterarpen.static_proxy;
public interface IUserService {
void add();
void delete();
void update();
void query(String name);
}
UserServiceImpl.java:
package com.sterarpen.static_proxy;
public class UserServiceImpl implements IUserService {
@Override
public void add() {
// TODO Auto-generated method stub
System.out.println("add a user");
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("delete a user");
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("update a user");
}
@Override
public void query(String name) {
// TODO Auto-generated method stub
System.out.println("query a user whose name is " + name);
}
}
Proxy.java:
package com.sterarpen.static_proxy;
public class Proxy implements IUserService{
private IUserService userService;
public Proxy() {
// TODO Auto-generated constructor stub
userService = new UserServiceImpl();
}
public Proxy(IUserService userService) {
super();
this.userService = userService;
}
public IUserService getUserService() {
return userService;
}
public void setUserService(IUserService userService) {
this.userService = userService;
}
@Override
public void add() {
// TODO Auto-generated method stub
log("add");
userService.add();
}
@Override
public void delete() {
// TODO Auto-generated method stub
log("delete");
userService.delete();
}
@Override
public void update() {
// TODO Auto-generated method stub
log("update");
userService.update();
}
@Override
public void query(String name) {
// TODO Auto-generated method stub
log("query");
userService.query(name);
}
protected void log(String op) {
System.out.println(">>run to " + op + "<<");
}
}
Test.java:
package com.sterarpen.static_proxy;
public class Test {
public static void main(String[] args) {
Proxy p = new Proxy(new UserServiceImpl());
p.add();
p.query("张晓");
}
}
Result:
缺点:每增加一个需要被代理的类就需要增加一个对应代理类,会导致开发效率降低。
动态代理
-
JDK动态代理
-
CGLIB动态代理
JDK动态代理
案例1
Star.java:
package com.sterarpen.proxy;
public interface Star {
String sing(String music_name);
void dance();
}
BigStar.java:
package com.sterarpen.proxy;
public class BigStar implements Star {
private String name;
public BigStar(String name) {
this.name = name;
}
public String sing(String music_name) {
System.out.println(this.name + "正在唱:" + music_name);
return "谢谢---";
}
public void dance() {
System.out.println(this.name + "正在跳舞");
}
}
ProxyUtil.java:
package com.sterarpen.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Star getProxy(BigStar s) {
Star star = (Star)Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[] {Star.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if(method.getName().equals("sing")) {
System.out.println("准备唱歌");
} else if(method.getName().equals("dance")) {
System.out.println("准备跳舞");
}
return method.invoke(s, args);
}
});
return star;
}
}
Test.java:
package com.sterarpen.proxy;
public class Test {
public static void main(String[] args) {
ProxyUtil p = new ProxyUtil();
Star s = (Star)p.getProxy(new BigStar("刘亦菲"));
System.out.println(s.sing("兰若词"));
s.dance();
}
}
Result:
案例2
WhiteWineCompany.class:
package com.sterarpen.demo5;
public interface WhiteWineCompany {
void product();
}
Moutai.class:
package com.sterarpen.demo5;
public class Moutai implements WhiteWineCompany {
@Override
public void product() {
System.out.println("生产贵州茅台");
}
}
JDKProxy:
package com.sterarpen.demo5;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("京东商城下单");
Object result = method.invoke(target, args);
System.out.println("京东商城发快递");
return result;
}
public Object getJDKProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
}
Client.class:
package com.sterarpen.demo5;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Client {
public static void main(String[] args) {
JDKProxy jdkProxy = new JDKProxy();
jdkProxy.setTarget(new Moutai());
WhiteWineCompany proxy = (WhiteWineCompany) jdkProxy.getJDKProxy();
proxy.product();
}
}
Result: