Spring AOP
研读了下有关Spring AOP的blog:
1. http://blog.csdn.net/wuxinzaiyu/article/details/8608394
2. http://snowolf.iteye.com/blog/1481442
Spring AOP的底层实现使用的是JDK动态代理(针对implements接口的类) / CGLib动态代理(针对未实现接口的类)。总体来说,Spring AOP使用起来比较容易。分XML配置和注解两种方式。
目前自己的使用方式有两种(均为注解方式):
1. XML中增加<aop:aspectj-autoproxy/> ; 在代理类上添加@Aspect注解
2. 在代理类上添加@EnableAspectJAutoProxy和@Aspect
采用第二种方式时,有以下参考实例:
1. 接口和实现:
public interface UserDAO { public void save(User user); }
public class UserDAOImpl implements UserDAO { @Override public void save(User user) { System.out.println("save start..."); } }
2. 代理类:
@EnableAspectJAutoProxy @Aspect @Component public class LogInterceptor { @Before(value = "execution(public void foo.bar.dao.Impl.UserDAOImpl.save(foo.bar.entity.User))") public void before(){ System.out.println("before method..."); } }
3. spring-config.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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:annotation-config /> <context:component-scan base-package="foo.bar"/> <!--<aop:aspectj-autoproxy/>--> <bean id="userDAO" class="foo.bar.dao.Impl.UserDAOImpl"/> </beans>
4. Test
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserDAO userDAO = (UserDAO)context.getBean(UserDAO.class); User user = new User(); userDAO.save(user); } }
5. 测试结果:
before method...
save start...
注意:Spring AOP只能对Spring管理的beans起作用!!!也就是说,Spring AOP对人为new的对象不起任何作用。
XML配置Spring AOP方式(推荐),原因:Spring中有很多已经写好的切面类,如果调用这些,只能通过XML配置Pointcut。
实例:
先去掉以上第2步中的注解,并将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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:annotation-config /> <context:component-scan base-package="foo.bar"/> <bean id="userDAO" class="foo.bar.dao.Impl.UserDAOImpl"/> <bean id="logIntercept" class="foo.bar.proxy.LogInterceptor"/> <aop:config> <aop:pointcut id="log" expression="execution(public void foo.bar.dao.Impl.UserDAOImpl.save(foo.bar.entity.User))"/> <aop:aspect id="logAspect" ref="logIntercept"> <aop:before method="before" pointcut-ref="log"/> </aop:aspect> </aop:config> </beans>
基本上一看就明白。
-----------------------------------------------------------------------------------------------------------------
1. 注解方式使用Spring AOP:
1. XML中添加<aop:aspectj-autoproxy/>
2. 定义切面类LogInterpetor
3. 切面类上添加注解@Aspect和@Component
4. 定义切面@Pointcut及Advice
2. XML方式使用Spring AOP:
1. 实例化切面类
2. 配置aop:config,aop:pointcut,aop:aspect 以及各种Advice