spring aop简单理解(xml方式的)
aop原理是spring帮我们封装了动态代理,然后我们只管写具体的业务,我们将公共业务也写到具体的一个类中并实现spring为我们提供的对应要连接切入哪个位置的接口,然后再xml中配置它们的关系即可。
优点:和动态代理一样,具体实现只管具体实现使的代码更加纯粹,公共业务只需实现自己对应的接口,然后编码即可,有了动态代理的好处,又没有手写动态代理那么复杂,这就是aop(被分装后的动态代理)。
1.UserService接口:
package mr.li.service; public interface UserService { void add(); void remove(); }
2.UserServiceImpl实现类:
package mr.li.service.impl; import mr.li.service.UserService; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("添加一条数据"); } @Override public void remove() { System.out.println("删除一条数据"); } }
3.前置切面:Log日志打印
package mr.li.log; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; /** * 前置切面:日志打印 * @author yanLong.Li * @date 2019年3月16日 下午10:33:22 */ public class Log implements MethodBeforeAdvice{ @Override public void before(Method method, Object[] arg1, Object target) throws Throwable { System.out.println("aop前置:"+target.getClass().getName()+"类的"+ method + "方法执行了~~"); } }
4后置切面:AfterLog 日志打印
package mr.li.log; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; /** * 后置切面:日志打印 * @author yanLong.Li * @date 2019年3月16日 下午10:33:44 */ public class AfterLog implements AfterReturningAdvice{ @Override public void afterReturning(Object result, Method method, Object[] arg2, Object target) throws Throwable { System.out.println("aop后置:"+target.getClass().getName()+"类的"+ method + "方法执行了,返回结果为"+result); } }
5.xml关系配置
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="mr.li.service.impl.UserServiceImpl"/> <bean id = "log" class="mr.li.log.Log"/> <bean id = "afterLog" class="mr.li.log.AfterLog"/> <aop:config> <!-- 配置被切入的哪个类使用 execution表达式 *表示所有的 ..标识所有的参数 --> <aop:pointcut expression="execution(* mr.li.service.impl.UserServiceImpl.*(..))" id="aoop"/> <!-- 设置要切入的类:切面 --> <aop:advisor advice-ref="log" pointcut-ref="aoop"/> <aop:advisor advice-ref="afterLog" pointcut-ref="aoop"/> </aop:config> </beans>
6.测试类
package mr.li.client; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import mr.li.service.UserService; public class Client { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) applicationContext.getBean("userService"); userService.remove(); userService.add(); } }
打印结果:
aop前置:mr.li.service.impl.UserServiceImpl类的public abstract void mr.li.service.UserService.remove()方法执行了~~
删除一条数据
aop后置:mr.li.service.impl.UserServiceImpl类的public abstract void mr.li.service.UserService.remove()方法执行了,返回结果为null
aop前置:mr.li.service.impl.UserServiceImpl类的public abstract void mr.li.service.UserService.add()方法执行了~~
添加一条数据
aop后置:mr.li.service.impl.UserServiceImpl类的public abstract void mr.li.service.UserService.add()方法执行了,返回结果为null