静态代理:
创建项目:
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();
-
- }
- }