第一个版本
1)第一个版本:业务和切面紧耦合在一起,没有拆分.
/*** 图书购买业务和事务切面耦合在一起*/public class BookServiceImpl {public void buy(){try {System.out.println("事务开启.......");System.out.println("图书购买业务功能实现...........");System.out.println("事务提交.......");} catch (Exception e) {System.out.println("事务回滚.......");}}}
第二个版本
2)第二个版本:使用子类代理的方式拆分业务和切面.
/*** 使用子类代理的方式进行图书业务和事务切面的拆分*/public class BookServiceImpl {//在父类中只有干干净净的业务public void buy(){System.out.println("图书购买功能实现........");}}
/*** 子类就是代理类,将父类的图书购买功能添加事务切面*/public class SubBookServiceImpl extends BookServiceImpl {@Overridepublic void buy() {try {//事务切面System.out.println("事务开启.........");//主业务实现super.buy();//事务切面System.out.println("事务提交.........");} catch (Exception e) {System.out.println("事务回滚.........");}}}
public class MyTest02 {@Testpublic void test02(){BookServiceImpl service = new SubBookServiceImpl();service.buy();}}
第三个版本
3)第三个版本:使用静态代理拆分业务和切面.业务和业务接口已拆分.此时切面紧耦合在业务中.
public interface Service {//规定业务功能void buy();}
/*** 目标对象:业务功能的具体实现*/public class BookServiceImpl implements Service {@Overridepublic void buy() {System.out.println("图书购买业务功能实现............");}}
public class ProductServiceImpl implements Service {@Overridepublic void buy() {System.out.println("商品购买业务实现.........");}}
/*** 静态代理已经实现了目标对象的灵活切换* 图书购买业务,商品购买业务*/public class Agent implements Service {//设计成员变量的类型为接口,为了灵活切换目标对象public Service target;//使用构造方法传入目标对象public Agent(Service target){this.target = target;}@Overridepublic void buy() {try {//切面功能System.out.println("事务开启......"); //日志 权限验证//业务功能target.buy();//切面功能System.out.println("事务提交.......");} catch (Exception e) {System.out.println("事务回滚.......");}}}
public class MyTest03 {@Testpublic void test02(){Service agent = new Agent(new ProductServiceImpl());agent.buy();}}
第四个版本
4)第四个版本:使用静态代理拆分业务和业务接口,切面和切面接口.
public interface Service {//规定业务功能void buy();}
/*** 目标对象:业务功能的具体实现*/public class BookServiceImpl implements Service {@Overridepublic void buy() {System.out.println("图书购买业务功能实现............");}}
public class ProductServiceImpl implements Service {@Overridepublic void buy() {System.out.println("商品购买业务实现.........");}}
public interface AOP {//该方法不用 必须实现,用到实现即可default void before(){}default void after(){}default void exception(){}}
public class LogAop implements AOP {@Overridepublic void before() {System.out.println("前置日志输出.......");}}
public class TransAop implements AOP {@Overridepublic void before() {System.out.println("事务开启........");}@Overridepublic void after() {System.out.println("事务提交........");}@Overridepublic void exception() {System.out.println("事务回滚........");}}
public class Agent implements Service {//传入目标(业务)对象,切面对象Service target;AOP aop;//使用构造方法初始化业务对象和切面对象public Agent(Service target,AOP aop){this.target = target;this.aop = aop;}@Overridepublic void buy() {try {//切面aop.before(); //事务 日志//业务target.buy(); //图书 商品//切面aop.after(); //事务} catch (Exception e) {//切面aop.exception();}}}
public class MyTest04 {@Testpublic void test02(){Service agent = new Agent(new ProductServiceImpl(),new TransAop());//切入多个切面的功能Service agent1 = new Agent(agent,new LogAop());agent1.buy();}}
第五个版本
5)第五个版本:使用动态代理完成第四个版本的优化.
public interface Service {//规定业务功能void buy();//增加有参有返回值的方法测试代理功能default String show(int age){return null;}}
/*** 目标对象:业务功能的具体实现*/public class BookServiceImpl implements Service {@Overridepublic void buy() {System.out.println("图书购买业务功能实现............");}@Overridepublic String show(int age) {System.out.println("这是show()方法被调用...."+age);return "abcd";}}
public class ProductServiceImpl implements Service {@Overridepublic void buy() {System.out.println("商品购买业务实现.........");}}
public interface AOP {default void before(){}default void after(){}default void exception(){}}
public class LogAop implements AOP {@Overridepublic void before() {System.out.println("前置日志输出.......");}}
public class TransAop implements AOP {@Overridepublic void before() {System.out.println("事务开启........");}@Overridepublic void after() {System.out.println("事务提交........");}@Overridepublic void exception() {System.out.println("事务回滚........");}}
public class ProxyFactory {public static Object getAgent(Service target,AOP aop){//返回生成的动态代理对象return Proxy.newProxyInstance(//类加载器target.getClass().getClassLoader(),//目标对象实现的所有的接口target.getClass().getInterfaces(),//代理功能实现new InvocationHandler() {@Overridepublic Object invoke(//生成的代理对象Object proxy,//正在被调用的目标方法buy(),show()Method method,//目标方法的参数Object[] args) throws Throwable {Object obj = null;try {//切面aop.before(); //事务 日志//业务obj = method.invoke(target,args);//切面aop.after();} catch (Exception e) {//切面aop.exception();}return obj; //目标方法的返回值}});}}
public class MyTest05 {@Testpublic void test02(){//得到动态代理对象Service agent = (Service) ProxyFactory.getAgent(new BookServiceImpl(),new TransAop());agent.buy();}@Testpublic void test03(){//得到动态代理对象Service agent = (Service) ProxyFactory.getAgent(new BookServiceImpl(),new LogAop());System.out.println(agent.getClass());String s = agent.show(22);System.out.println(s);}}
Spring原生AOP代码实现(了解)
重要的是Aspect框架
public interface BookService {public boolean buy(String userName,String bookName,double price);public void comment(String userName,String comments);}
public class BookServiceImpl implements BookService {@Overridepublic boolean buy(String userName, String bookName, double price) {System.out.println("购买图书功能实现...........");System.out.println(userName+"购买了"+bookName+",花费了"+price+"元.");System.out.println(userName+"增加了"+(price/10));System.out.println("图书购买业务结束");return false;}@Overridepublic void comment(String userName, String comments) {System.out.println("评论功能的实现 ...........");System.out.println(userName+"发表了"+comments+".");System.out.println("评论功能结束 ...........");}}
public class LogAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");System.out.println("\n[系统日志]"+sf.format(new Date())+"---"+method.getName()+ Arrays.toString(objects));}}
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--创建业务对象--><bean id ="bookServiceTarget" class="com.bjpowernode.service.impl.BookServiceImpl"></bean><!--创建切面的对象--><bean id="logAdvice" class="com.bjpowernode.advice.LogAdvice"></bean><!--绑定业务和切面--><bean id="bookService" class="org.springframework.aop.framework.ProxyFactoryBean"><!--配置业务接口--><property name="interfaces" value="com.bjpowernode.service.BookService"></property><!--配置切面--><property name="interceptorNames"><list><value>logAdvice</value></list></property><!--织入--><property name="target" ref="bookServiceTarget"></property></bean></beans>
public class MyTest {@Testpublic void test01(){ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");BookService proxy = (BookService) ac.getBean("bookService");System.out.println(proxy.getClass());proxy.buy("张三","平凡的世界",55);proxy.comment("张三","还是很好看,可以看一看.....");}}
