1. 什么是代理模式:
代理:自己不做,找人帮你做。
代理模式:在一个原有功能的基础上添加新的功能。
分类:静态代理和动态代理。
2. 静态代理
2.1 原有方式:核心业务和服务方法都编写在一起
public class TeamService {
public void add(){
try {
System.out.println("开始事务");
// 核心业务
System.out.println("TeamService---- add----");
System.out.println("提交事务");
} catch (Exception e) {
e.printStackTrace();
System.out.println("回滚事务");
}
}
}
2.2 基于类的静态代理
将服务性代码分离出来,核心业务–保存业务中只有保存功能
public class TeamService {
public void add(){
System.out.println("TeamService---- add----");
// 核心业务
}
}
核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
public class ProxyTeamService extends TeamService {
public void add(){
try {
System.out.println("开始事务");
super.add();
System.out.println("提交事务");
}catch (Exception e){
System.out.println("回滚事务");
}
}
}
弊端:代理类只能代理一个类
2.3 基于接口的静态代理
为核心业务(保存add)创建一个接口,通过接口暴露被代理的方法
要求:代理类和被代理类都实现了同一个接口
接口定义核心方法:
public interface IService {
void add();
}
public class TeamService implements IService{
@Override
public void add(){
System.out.println("TeamService---- add----");// 核心业务
}
}
public class UserService implements IService{
@Override
public void add() {
System.out.println("UserService---- add-----"); // 核心业务
}
}
代理类和被代理类实现同一个接口
事务代理类:
public class ProxyTranService implements IService {
private IService service;//被代理的对象
public ProxyTranService(IService service) {
this.service = service;
}
@Override
public void add() {
try {
System.out.println("开始事务");
service.add();
//核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
System.out.println("提交事务");
}catch (Exception e){
System.out.println("回滚事务");
}
}
}
日志代理类:
public class ProxyLogService implements IService {
private IService service;//被代理对象
public ProxyLogService(IService service) {
this.service = service;
}
@Override
public void add() {
try {
System.out.println("开始日志");
service.add();
//核心业务就是由被代理对象完成 ;其他服务功能由代理类完成
System.out.println("结束日志");
}catch (Exception e){
System.out.println("异常日志");
}
}
}
测试类:
public static void main(String[] args) {
TeamService teamService=new TeamService();//被代理对象
UserService userService=new UserService();//被代理对象
ProxyTranService tranService=new ProxyTranService(userService);
//事务代理 对象--一级代理
//tranService.add();//代理对象干活
ProxyLogService logService=new ProxyLogService(tranService);
//日志的代理对 象--二级代理
logService.add();
}
2.4 提取出切面代码,作为AOP接口(优化)
切面:类似于服务性代码,要切入到核心的代码当中
共有4个位置可以将切面代码编织进入核心业务代码中。
切面接口:
public interface AOP {
void before();
void after();
void exception();
void myFinally();
}
事务切面类:
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");
}
}
日志切面类:
public class LogAop 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");
}
}
代理类:
public class ProxyAOPService implements IService {
private IService service;//被代理对象
private AOP aop;//要加入切面
public ProxyAOPService(IService 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(){
IService teamService=new TeamService();//被代理对象--核心内容
AOP logAop=new LogAop();//切面-服务内容
AOP tranAop=new TranAOP();
//代理对象--一级 代理
IService service=new ProxyAOPService(teamService,logAop);
//代理对象--二级代理
IService service2=new ProxyAOPService(service,tranAop);
service2.add();
}
总结静态代理:
- 可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
- 缺点: 因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。
一旦接口增加方法,目标对象与代理对象都要维护。