静态代理
package com.dream.demo1;
public interface Rent {
void rent();
}
package com.dream.demo1;
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东出租房子");
}
}
package com.dream.demo1;
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
host.rent();
seeHouse();
fare();
}
public void seeHouse(){
System.out.println("带你看房");
}
public void fare(){
System.out.println("收中介费");
}
}
package com.dream.demo1;
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
代理人帮房东出租房子,客户直接找代理就可以租到房了,这就是一种静态代理模式
在实际业务中
package com.dream.demo2;
public interface UserService {
void add();
void delete();
void update();
void query();
}
package com.dream.demo2;
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}
@Override
public void delete() {
System.out.println("删除了一个用户");
}
@Override
public void update() {
System.out.println("修改了一个用户");
}
@Override
public void query() {
System.out.println("查询了一个用户");
}
}
如果要增加一个日志功能,可以用代理类来实现
package com.dream.demo2;
public class UserServiceProxy implements UserService{
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void delete() {
log("delete");
userService.delete();
}
@Override
public void update() {
log("update");
userService.update();
}
@Override
public void query() {
log("query");
userService.query();
}
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
测试
package com.dream.demo2;
public class Test {
public static void main(String[] args) {
UserServiceProxy userServiceProxy = new UserServiceProxy();
userServiceProxy.setUserService(new UserServiceImpl());
userServiceProxy.add();
}
}
我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想
动态代理
分为基于接口动态代理(JDK动态代理)和基于类的动态代理(cglib)
package com.dream.demo3;
public interface Rent {
void rent();
}
package com.dream.demo3;
public class Host implements Rent{
@Override
public void rent() {
System.out.println("出租房屋");
}
}
package com.dream.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandle implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent){
this.rent=rent;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
fare();
return method.invoke(rent,args);
}
public void seeHouse(){
System.out.println("带客户看房");
}
public void fare(){
System.out.println("收中介费");
}
}
package com.dream.demo3;
public class Client {
public static void main(String[] args) {
Host host = new Host();
ProxyInvocationHandle handle = new ProxyInvocationHandle();
handle.setRent(host);
Rent proxy = (Rent) handle.getProxy();
proxy.rent();
}
}
一个动态代理可以代理多个类,一般代理某一类业务,代理的是接口
利用动态代理来实现之前业务代码的增强
package com.dream.demo2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String methodName){
System.out.println("执行了"+methodName+"方法");
}
}
package com.dream.demo2;
public class Test {
public static void main(String[] args) {
UserServiceImpl service = new UserServiceImpl();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(service);
UserService proxy = (UserService) handler.getProxy();
proxy.query();
}
}