SSM——AOP静态代理——Day02

1、什么是AOP       2、Spring核心-AOP-代理&静态代理1

3、Spring核心-AOP-静态代理2        4、对于静态代理的总结:

1、什么是AOP

         1)AOP为Aspect Oriented Programming的缩写,意思为面向切面编程,是通过预编译方式                 和运行期动态 代理实现程序功能的统一维护的一种技术。

         2)AOP 的作用:不修改源码的情况下,程序运行期间对方法进行功能增强
         3)好处: 减少代码的重复,提高开发效率,便于维护。 专注核心业务的开发。   
                          核心业   务和服务性代码混合在一起 开发中:各自做自己擅长的事情,运行的时                            候将服务性代码织入到核心业务中。 通过spring 工厂自动实现将服务性代码以切                              面的方式加入到核心业务代码中。

 2、Spring核心-AOP-代理&静态代理1

1)代理模式 :自己不做,找人帮你做。 在一个原有功能的基础上添加新的功能。

     分类:静态代理和动态代理。
2)举个例子来说明代理模式
创建一个service在这个类的方法中,除了核心业务之外,还有很多相同的代码,用于服务的,所以我们要把他们分开
public class TeamService {

    public void add(){
//        try {
//            System.out.println("开始事务");
            System.out.println("TeamService----------add------------");//核心业务
//            System.out.println("提交事务");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    public void update(){
//        try {
//            System.out.println("开始事务");
            System.out.println("TeamService----------update------------");//核心业务
//            System.out.println("提交事务");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }
}

创建一个静态代理类:

import com.zj.service.TeamService;

//静态代理类要继承我们被代理的类
public class ProxyTeamService extends TeamService {
    //在调用方法的时候,调用该方法,提高的代码的功能添加。同时实现了服务代码也业务代码分离
    public void add(){
        try {
            System.out.println("开始事务");
            super.add();
            System.out.println("提交事务");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void update(){
        try {
            System.out.println("开始事务");
            super.update();
            System.out.println("提交事务");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

但是这样做有个弊端,就是service类越多,代理类就越多。

3)修改:改为基于接口的动态代理类。

在service包下建立一个接口,接口里面只定义一个方法,然后编写一个serviceImpl来实现他。

package com.zj.service;

public interface TeamService {
    
    void add();
}
package com.zj.service.impl;

import com.zj.service.TeamService;

public class TeamServiceImpl implements TeamService {

    @Override
    public void add() {
        System.out.println("TeamService-----add-----");
    }
}

写一个基于接口的静态代理类

package com.zj.staticProxy;

import com.zj.service.TeamService;

/**
 * 这是一个有关事务的静态代理
 */
//代理类和被代理类要实现同一个接口
public class ProxyTranService implements TeamService {
    //通过多态的方式,定义一个被代理的类
    private TeamService teamServiceImpl;

    //在代理对象中,你必须将被代理的对象复制进来,
    //你可以通过通过构造方法,也可以通过set方法将他弄进来


    public void setTeamServiceImpl(TeamService teamServiceImpl) {
        this.teamServiceImpl = teamServiceImpl;
    }

    @Override
    public void add() {
        try {
            System.out.println("开始事务");
            teamServiceImpl.add();
            System.out.println("结束事务");
        } catch (Exception e) {
            System.out.println("事务的回滚");
        }
    }
}

写一个测试类

package com.zj.test.Test01;

import com.zj.service.impl.TeamServiceImpl;
import com.zj.staticProxy.ProxyTranService;
import org.junit.Test;

public class Test01 {
    @Test
    public void test01(){
        //创建一个被代理的对象
        TeamServiceImpl teamService = new TeamServiceImpl();
        //创建一个代理对象
        ProxyTranService proxyTranService = new ProxyTranService();
        proxyTranService.setTeamServiceImpl(teamService);
        proxyTranService.add();
    }
}

基于接口的代理,只需要将set里面的对象改变,就可以实现同一个代理类代理多个被代理类。

值得注意的是,代理类和被代理类需要实现同一个接口。

4)我在用一个例子来完美诠释基于接口的静态代理:

场景:有一个明星,他请了一个代理人来帮他管理事务,然后他又让这个管理事务的人去请了一个来管理日志的人,通过这样的方式,明星就可以既有人帮他管理事务,又有人帮他管理日志。

这里有一个接口,一个接口的实现类,有两个代理,一个是事务代理,一个是日志代理。

接口:

public interface TeamService {

    void add();
}

实现类:

import com.zj.service.TeamService;
public class UserServiceImpl implements TeamService {
    @Override
    public void add() {
        System.out.println("userServceImpl--------add");
    }
}

事务代理类;

import com.zj.service.TeamService;
/**
 * 这是一个有关事务的静态代理
 */
//代理类和被代理类要实现同一个接口
public class ProxyTranService implements TeamService {
    //通过多态的方式,定义一个被代理的类
    private TeamService teamServiceImpl;

    //在代理对象中,你必须将被代理的对象复制进来,
    //你可以通过通过构造方法,也可以通过set方法将他弄进来


    public ProxyTranService(TeamService teamServiceImpl) {
        this.teamServiceImpl = teamServiceImpl;
    }

    @Override
    public void add() {
        try {
            System.out.println("开始事务");
            teamServiceImpl.add();
            System.out.println("结束事务");
        } catch (Exception e) {
            System.out.println("事务的回滚");
        }
    }
}

日志代理类:

import com.zj.service.TeamService;

public class ProxyLogService implements TeamService {

    private TeamService teamService;

    public ProxyLogService(TeamService teamService) {
        this.teamService = teamService;
    }

    @Override
    public void add() {
        try {
            System.out.println("开始日志");
            teamService.add();
            System.out.println("结束日志");
        } catch (Exception e) {
            System.out.println("异常日志");
        }
    }
}

测试类(将我们想要的效果,通过调用这些类来实现)

import com.zj.service.impl.TeamServiceImpl;
import com.zj.service.impl.UserServiceImpl;
import com.zj.staticProxy.ProxyLogService;
import com.zj.staticProxy.ProxyTranService;
import org.junit.Test;

public class Test01 {
    @Test
    public void test01(){
      //创建被代理的对象
        TeamServiceImpl teamService = new TeamServiceImpl();
        UserServiceImpl userService = new UserServiceImpl();
        //创建事务代理对象
        ProxyTranService proxyTranService = new ProxyTranService(userService);
        //在事务代理的基础之上,我想给他加一个日子代理
        ProxyLogService proxyLogService = new ProxyLogService(proxyTranService);
        proxyLogService.add();
    }
}

运行结果:

开始日志
开始事务
userServceImpl--------add
结束事务
结束日志

3、Spring核心-AOP-静态代理2

1、对于上诉的代码,仍然有很多的冗余,这个时候,我们在用面向切面编程思想将他优化一下。

2、用一个小小的案例来演示一下吧

创建一个aop包,包下写一个接口,和两个实现类

public interface AOP {
    /**
     * 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
     */
    void before();
    void after();
    void exception();
    void myFinally();
}
import com.zj.aop.AOP;

public class TranAop implements AOP {
    /**
     * 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
     */
    @Override
    public void before() {
        System.out.println("事务----------before--------");
    }

    @Override
    public void after() {
        System.out.println("事务----------after--------");
    }

    @Override
    public void exception() {
        System.out.println("事务----------exception--------");
    }

    @Override
    public void myFinally() {
        System.out.println("事务----------myFinally--------");
    }
}
import com.zj.aop.AOP;

public class LogAopImpl implements AOP {

    /**
     * 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
     */
    @Override
    public void before() {
        System.out.println("日志---------before----------");
    }

    @Override
    public void after() {
        System.out.println("日志---------after----------");
    }

    @Override
    public void exception() {
        System.out.println("日志---------exception----------");

    }

    @Override
    public void myFinally() {
        System.out.println("日志---------myFinally----------");

    }
}

创建一个代理类

import com.zj.aop.AOP;
import com.zj.service.TeamService;

//代理类是要实现service层的接口
public class ProxyAopService implements TeamService {
    //在代理类中,我们要定义被代理的类
    private TeamService service;
    //在代理类中,我们要定义切片
    private AOP aop;
    //在代理类中,我们要将被代理的类的对象赋给代理类

    public ProxyAopService(TeamService service, AOP aop) {
        this.service = service;
        this.aop = aop;
    }

    @Override
    //在这里我们将切片插入到对于的位置
    public void add() {
        try {
            aop.before();
            service.add();//被代理的对象去干活
            aop.after();
        } catch (Exception e) {
            aop.exception();
        } finally {
            aop.myFinally();
        }
    }
}

定义一个测试类

 @Test
    public void test02(){
        //创建被代理的对象
        TeamService userService = new UserServiceImpl();
        //创建切片对象
        AOP logAop = new LogAopImpl();
        AOP tranAop = new TranAop();
        //创建代理类对象
        ProxyAopService proxyAopService = new ProxyAopService(userService,logAop);//被代理对象----一级代理
        ProxyAopService proxyAopService1 = new ProxyAopService(proxyAopService,tranAop);//被代理对象----二级代理
        //调用方法
        proxyAopService1.add();
    }

结果:

事务----------before--------
日志---------before----------
userServceImpl--------add
日志---------after----------
日志---------myFinally----------
事务----------after--------
事务----------myFinally--------

4、对于静态代理的总结:

在不改变核心代码的前提下,通过通过静态代理,将核心代码和切面联系起来,增加他的功能,扩展他的功能。但是也有缺点,但我们的接口中的方法变更,我们就要去改变所有的实现类。还有就是代理类和被代理类要去实现同一个接口,就会导致出现很多的代理类。这也是一个弊端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值