我么在学习框架的时候我们知道,像这些增删改查的业务都应该处于事务的环境下.事务最适合添加的这一层是业务逻辑层.也就是我们所谓的service.我们现在新建一个java项目.在src下顶一个service的包.里面有个UserService接口
package service;
public interface UserService {
void addUser();
void deleteUser();
}
service包下有个impl的子包,里面是UserService的实现类UserServiceImpl
package service.impl;
import service.UserService;
public class UserServiceImpl implements UserService {
/*
* 这里正常应该是调用dao的方法,这里我们就用输出语句代替了
*/
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
UserServiceImpl的代码我们前面已经写成这个样子了,现在我希望添加事务的管理.事务我们知道:在UserServiceImpl里面增删改查的代码执行之前应该有开始事务,结束有提交事务 .现在想模拟一下这个过程.希望在UserServiceImpl里的增删改查的代码执行之前,都用打印"开启事务"来代替,结束打印"提交事务".
在不考虑spring之前,我们想要实现上面的过程,应该如何实现的呢?
首先我们考虑到,这些事务的添加和提交不能写在UserServiceImpl这类里面.咱们每个类都应该遵从单一原则.UserServiceImpl这个类只是处理增删改查,它与所谓的在不在事务里面没有关系.为了实现上面的要求,我们下面来介绍一下代理:
代理:
对象访问前后实现预处理,过滤等处理.代理可以在不改动目标对象的基础上,增加其他额外的功能(扩展功能)。
代理模式:这里我们主要说静态代理
静态代理:编译期间为每个委托类创建代理类
现在我们的委托类是UserServiceImpl,现在需要代理类来代理UserServiceImpl,首先代理类肯定要知道UserServiceImpl这个委托类里面有怎样的方法.这里说一下使用静态代理的一个前:需要我们的代理类和委托类实现同一个接口或者是继承相同父类。
那我们现在写一下代理的代码,先在service先创建一个子包proxy.里面创建代理类UserServiceProxy
package service.proxy;
import service.UserService;
/*
* 代理类
*/
public class UserServiceProxy implements UserService {
/*
* 这个代理类并不是真正做事的.
*/
UserService service;
public UserServiceProxy(UserService service) {
this.service = service;
}
@Override
public void addUser() {
System.out.println("开启事务");
service.addUser();
System.out.println("提交事务");
}
@Override
public void deleteUser() {
System.out.println("开启事务");
service.deleteUser();
System.out.println("提交事务");
}
}
下面我们在测试类里测试一下:
package test;
import service.UserService;
import service.impl.UserServiceImpl;
import service.proxy.UserServiceProxy;
public class Test {
@org.junit.Test
public void test(){
//代理对象,把目标对象传给代理对象,建立代理关系
UserService proxy = new UserServiceProxy(new UserServiceImpl());
//执行的是代理的方法,实际上是调用了委托类的方法
proxy.addUser();
proxy.deleteUser();
}
}
上面就是我们所说的静态代理.
可以实现在不修改目标对象的基础上,对目标对象的功能进行扩展。
但是由于代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.而且类似上面的每一个方法都要添加开启事务和提交事务的代码,冗余太多了.
那如果解决上面的出现的问题,就是我们后面要讲的:可以使用动态代理方式来解决。