AOP面向切面编程
AOP可以实现“业务代码”和“关注点代码”完全分离
@Override public List<Message> findAllMessage() { Session session = null; //关注点代码 Transaction tx = null; try{ session = HibernateUtils.getSession(); tx = session.beginTransaction(); //关注点代码 Query q = session.createQuery("from Message order by write_time desc "); //业务代码 return q.list(); //业务代码 }catch (Exception e){ throw new RuntimeException(e); //关注点代码 }finally { tx.commit(); session.close(); //关注点代码 } }
分析:
关注点代码,就是指重复执行的代码。
业务代码和关注点代码分离,好处?
--关注点代码写一次即可
--开发者只需要关注核心业务
--运行期间,执行业务代码的时候动态的植入关注点代码;(代理实现)
如何分离
过程式/对象式/代理模式分离
手动实现aop编程实例一:
package aop; import org.springframework.stereotype.Component; /** * Created by cxspace on 16-8-10. */ @Component //加入ioc容器 public class Aop { //重复执行的代码 public void begin(){ System.out.println("开始事务"); } public void commite(){ System.out.println("提交事务"); } } package aop; /** * Created by cxspace on 16-8-10. */ public interface IUserDao { public void save(); } package aop; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * Created by cxspace on 16-8-10. */ @Component public class UserDao implements IUserDao{ @Resource private Aop aop; @Override public void save() { aop.begin(); System.out.println("保存数据!"); aop.commite(); } } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启注解扫描--> <context:component-scan base-package="aop"></context:component-scan> </beans> package aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by cxspace on 16-8-10. */ public class App { ApplicationContext ac = new ClassPathXmlApplicationContext("aop/bean.xml"); @Test public void test(){ IUserDao userDao = (IUserDao)ac.getBean("userDao"); userDao.save(); } }
手动实现AOP编程实例二(代理)
package aopProxy; /** * Created by cxspace on 16-8-10. */ public interface IUserDao { public void save(); } package aopProxy; import org.springframework.stereotype.Component; /** * Created by cxspace on 16-8-10. */ @Component public class UserDao implements IUserDao { @Override public void save() { System.out.println("保存数据!"); } } package aopProxy; import org.springframework.stereotype.Component; /** * Created by cxspace on 16-8-10. */ @Component //加入ioc容器 public class Aop { //重复执行的代码 public void begin(){ System.out.println("开始事务"); } public void commite(){ System.out.println("提交事务"); } } package aopProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by cxspace on 16-8-10. */ public class ProxyFactory { //目标对象 private static Object target; private static Aop aop; //生成代理对象方法 public static Object getProxyInstance(Object target_,Aop aop_){ target = target_; aop = aop_; return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { aop.begin(); Object returnValue = method.invoke(target,args); aop.commite(); return returnValue; } } ); } } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启注解扫描--> <context:component-scan base-package="aopProxy"></context:component-scan> <!--调用工厂方法,返回UserDao代理后的对象--> <bean id="userDao_proxy" class="aopProxy.ProxyFactory" factory-method="getProxyInstance"> <constructor-arg index="0" ref="userDao"></constructor-arg> <constructor-arg index="1" ref="aop"></constructor-arg> </bean> </beans> package aopProxy; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by cxspace on 16-8-10. */ public class App { ApplicationContext ac = new ClassPathXmlApplicationContext("aopProxy/bean.xml"); @Test public void test(){ IUserDao userDao = (IUserDao)ac.getBean("userDao_proxy"); System.out.println(userDao.getClass()); userDao.save(); } }
时间: 2024-11-19 17:35:12