静态代理:
创建项目:
Rent
package com.Li.demo01;
//租房
public interface Rent {
public void rent();
}
Proxy:
package com.Li.demo01;
//中介(负责找房东)
public class Proxy implements Rent{
//
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
host.rent();
}
}
Host:
package com.Li.demo01;
//房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
Client:
package com.Li.demo01;
public class Client {
public static void main(String[] args) {
Host host = new Host();
//代理
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
由于中介也需要房东,所以需要在此之前new一个房东。
你可能认为有没有效果都一样,但是在这个过程中,中介可以有自己的属性和方法。增加自己想要的内容。
修改之后
Proxy:(增加了自己的特有方法)
package com.Li.demo01;
//中介(负责找房东)
public class Proxy implements Rent{
//
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
seeHouse();
host.rent();
hetong();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//签合同
public void hetong(){
System.out.println("签租赁合同");
}
//收费
public void fare(){
System.out.println("收中介费");
}
}
此时就已经经过了中介之手,租到房了。
拓展:
新建demo02
UserService:
package com.Li.demo02;
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
UserServiceImpl:
package com.Li.demo02;
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("查询了一个用户");
}
}
UserServiceProxy:(代理类)(重点!)========相当于复制了一份原本的内容,这样操作出错的时候也不会影响原本内容。
package com.Li.demo02;
public class UserServiceProxy implements UserService{
//相当于在Proxy里面调取了UserServiceImpl
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("[debug] 使用了"+msg+"方法");
}
}
Client:(测试)
package com.Li.demo02;
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
UserServiceProxy proxy = new UserServiceProxy();
proxy.setUserService(userService);//中介(proxy)代理userService
proxy.add();
}
}
测试结果:
AOP就是横切进去,用来完善之前的业务。
动态代理:
· 动态代理和静态代理角色一样
· 动态代理的代理类是动态生成的,不是我们直接写好的!
· 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
·基于接口 — JDK动态代理【我们在这里使用】
·基于类:cglib
·java字节码实现:javassist
需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序。
Rent(接口)
package com.Li.demo03;
//租房
public interface Rent {
public void rent();
}
Host
package com.Li.demo03;
//房东
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
ProxyInvocationHandler(核心)(就相当于中介)
package com.Li.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//等会我们会用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到代理类
//(返回三个参数:用哪个类加载器去加载代理对象(中介),被代理的对象(房东),谁来进行这种new操作(运用invoke来操作)生成中介(也就是谁来生成中介))
//通过本程序的类加载器,来加载需要被代理的角色,生成代理类(三个参数的解释)
//一般只需要修改中间的参数就可以了
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();
//动态代理的本质,就是使用反射机制实现!
Object invoke = method.invoke(rent, args);
fare();
return invoke;
}
public void seeHouse(){
System.out.println("中介看房子");
}
public void fare(){
System.out.println("收中介费");
}
}
Client:(测试)
package com.Li.demo03;
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色:现在没有,但是有可以生成代理类的东西
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host);
//生成代理类
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}