1、什么是AOP 2、Spring核心-AOP-代理&静态代理1
3、Spring核心-AOP-静态代理2 4、对于静态代理的总结:
1、什么是AOP
1)AOP为Aspect Oriented Programming的缩写,意思为面向切面编程,是通过预编译方式 和运行期动态 代理实现程序功能的统一维护的一种技术。
2、Spring核心-AOP-代理&静态代理1
1)代理模式 :自己不做,找人帮你做。 在一个原有功能的基础上添加新的功能。
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、对于静态代理的总结:
在不改变核心代码的前提下,通过通过静态代理,将核心代码和切面联系起来,增加他的功能,扩展他的功能。但是也有缺点,但我们的接口中的方法变更,我们就要去改变所有的实现类。还有就是代理类和被代理类要去实现同一个接口,就会导致出现很多的代理类。这也是一个弊端。