业务:图书购买业务
切面:事务
第一个版本
业务和切面紧耦合在一起,没有拆分
package ys.com.proxy1;
public class BookServiceImpl {
public void buy(){
try{
System.out.println("事务开启");
System.out.println("图书购买业务功能实现");
System.out.println("事务提价");
}catch(Exception e){
System.out.println("事务回滚");
}
}
}
第二个版本
使用子类代理的方式拆分业务和切面
package ys.com.proxy2;
//使用子类代理的方式进行图书业务和事务切面的拆分
public class BookServiceImpl {
//父类只有的业务
public void buy(){
System.out.println("图书购买功能实现");
}
}
package ys.com.proxy2;
import ys.com.proxy2.BookServiceImpl;
//子类就是代理类,将父类的图书购买功能添加事务切面
public class SubBookServiceImpl extends BookServiceImpl {
@Override
public void buy() {
try{
//事务切面
System.out.println("事务开启");
//主业务实现
super.buy();
//事务切面
System.out.println("事务提交");
}catch (Exception e){
System.out.println("事务回滚");
}
}
}
package ys.com.main;
import ys.com.proxy2.BookServiceImpl;
import ys.com.proxy2.SubBookServiceImpl;
public class myapp {
public static void main(String[] args) {
BookServiceImpl bookService=new SubBookServiceImpl();
bookService.buy();
}
}
第三个版本
使用静态代理拆分业务和切面。业务和业务接口已拆分,此时切面紧耦合在业务中
package ys.com.proxy3;
public interface Service {
//规定业务功能
void buy();
}
package ys.com.proxy3;
//目标对象,业务功能实现
public class BookServiceImpl implements Service{
@Override
public void buy() {
System.out.println("图书购买功能实现");
}
}
package ys.com.proxy3;
public class ProductServiceImpl implements Service{
@Override
public void buy() {
System.out.println("商品购买业务实现");
}
}
package ys.com.proxy3;
//静态代理已经实现了目标对象的灵活切换
public class Agent implements Service{
// 设计成员变量的类型为接口,为了灵活切换目标对象
public Service service;
// 使用构造方法传入目标对象
public Agent(Service service){
this.service =service;
}
@Override
public void buy() {
try {
// 切面功能
System.out.println("事务开启");
// 业务功能
service.buy();
//切面功能
System.out.println("事务提交");
}catch (Exception e){
System.out.println("事务回滚");
}
}
}
package ys.com.main;
import ys.com.proxy3.Agent;
import ys.com.proxy3.BookServiceImpl;
import ys.com.proxy3.ProductServiceImpl;
import ys.com.proxy3.Service;
public class myapp {
public static void main(String[] args) {
Service service =new Agent(new ProductServiceImpl());
// Service service =new Agent(new BookServiceImpl());
//不同功能的灵活切换
service.buy();
}
}
第四个版本
使用静态代理拆分业务和业务接口,切面和切面接口
图片摘自 动力节点
package ys.com.proxy4;
//静态代理已经实现了目标对象的灵活切换
public class Agent implements Service {
// 设计成员变量的类型为接口,为了灵活切换目标对象
public Service service;
public AOP aop;
// 使用构造方法传入目标对象
public Agent(Service service, AOP aop) {
this.service = service;
this.aop = aop;
}
@Override
public void buy() {
try {
// 切面功能
aop.before();
// 业务功能
service.buy();
//切面功能
aop.after();
} catch (Exception e) {
aop.exception();
}
}
}
package ys.com.proxy4;
//切面接口
public interface AOP {
// void before();
// void after();
// void exception();
default void before(){}
default void after(){}
default void exception(){}
// 使用default 修饰的方法可以空实现,即接口的实现类不需要实现全部的方法
}
package ys.com.proxy4;
//切面实现类 日志
public class AopLogImpl implements AOP{
@Override
public void before() {
System.out.println("日志启动");
}
}
package ys.com.proxy4;
public class AopTransImpl implements AOP{
//切面实现类 事务
@Override
public void before() {
System.out.println("事务开启");
}
@Override
public void after() {
System.out.println("事务提交");
}
@Override
public void exception() {
System.out.println("事务回滚");
}
}
package ys.com.proxy4;
//目标对象,业务功能实现
public class BookServiceImpl implements Service {
@Override
public void buy() {
System.out.println("图书购买功能实现");
}
}
package ys.com.proxy4;
public class ProductServiceImpl implements Service {
@Override
public void buy() {
System.out.println("商品购买业务实现");
}
}
package ys.com.proxy4;
public interface Service {
//规定业务功能
void buy();
}
package ys.com.main;
import ys.com.proxy4.*;
public class myapp {
public static void main(String[] args) {
Service service =new Agent(new BookServiceImpl(),new AopLogImpl());
service.buy();
}
}
//多个切面切入的功能
public class myapp {
public static void main(String[] args) {
Service service =new Agent(new BookServiceImpl(),new AopLogImpl());
Service total =new Agent(service,new LogAop());
// 创建新的Service 对象,将前需要被切入的对象和切入的切面再次赋值给新的对象
total.buy();
}
}
第五个版本
使用动态代理完成第四个版本的优化
对Service接口进行修改
package ys.com.proxy5;
public interface Service {
//规定业务功能
void buy();
// 增加一个方法
default String show(int age){return "22";}
}
对BookServiceImpl实现类进行修改
package ys.com.proxy5;
//目标对象,业务功能实现
public class BookServiceImpl implements Service {
@Override
public void buy() {
System.out.println("图书购买功能实现");
}
@Override
public String show(int age) {
System.out.println("show方法被调用"+age);
return Service.super.show(age);
}
}
新建java类,进行动态代理
package ys.com.proxy5;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
public static Object getAgent(Service service,AOP aop){
return Proxy.newProxyInstance(
// 类加载器
service.getClass().getClassLoader(),
// 目标对象实现的所有的接口
service.getClass().getInterfaces(),
// 代理功能的实现
// 匿名内部类实现
new InvocationHandler() {
@Override
public Object invoke(
// 生成的代理对象
Object proxy,
// 正在被调用的目标方法
Method method,
// 目标方法的参数
Object[] args) throws Throwable {
Object object = null;
try {
// 切面
aop.before();
// 业务
object=method.invoke(service,args);
// 切面
aop.after();
} catch(Exception e){
// 切面
aop.exception();
}
return object;
}
}
);
}
}
修改主方法
package ys.com.main;
import ys.com.proxy5.*;
public class myapp {
public static void main(String[] args) {
// 获取动态代理对象
Service service =(Service)ProxyFactory.getAgent(new BookServiceImpl(),new AopLogImpl());
Service service1=(Service)ProxyFactory.getAgent(service,new AopTransImpl());
String s=service1.show(22);
System.out.println(s);
System.out.println("------------------------------------");
service1.buy();
}
}