参考
http://www.it165.net/pro/html/201407/18718.html
http://xtu-xiaoxin.iteye.com/blog/630206
http://m.blog.csdn.net/blog/zl3450341/6013727
目标对象类
package com.chuiyuan; public interface Employee { public void signIn (); }
实现为
package com.chuiyuan; public class CommonEmployee implements Employee { private String name ; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void signIn() { System.out.println(name+"已经签到"); } }
通知类
然后编写通知类AspectJLogger.java,在该通知类里,通过注入的形式来定义切面、通知以及通知所左右的切点,具体如下:
package com.chuiyuan; import java.util.Date; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * 使用@Aspect 注解的类, Spring 将会把它当作一个特殊的Bean(一个切面),也就是 * 不对这个类本身进行动态代理 */ @Aspect public class AspectJLogger { /** * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的 */ public static final String EDP = "execution( public * *(..))"; @Before(EDP) public void logBefore(){ System.out.println("logBefore:现在时间是:"+new Date()); } @After(EDP) //spring中After通知 public void logAfter() { System.out.println("logAfter:现在时间是:"+new Date()); } @Around(EDP) public Object logAround(ProceedingJoinPoint joinPoint){ System.out.println("logAround开始:现在时间是:"+new Date()); //方法执行前的代理处理 Object[] args = joinPoint.getArgs(); Object obj = null; try { obj = joinPoint.proceed(args); } catch (Throwable e) { e.printStackTrace(); } System.out.println("logAround结束:现在时间是:"+new Date()); //方法执行后的代理处理 return obj; } }
配置文件
<?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" 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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <aop:aspectj-autoproxy/> <bean id="aspect" class="com.chuiyuan.AspectJLogger" /> <bean id="employee" class="com.chuiyuan.CommonEmployee"> <property name="name" value="lsj"></property> </bean> </beans>
测试类
package com.chuiyuan; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class Test { public static void main(String [] args){ Resource res = new ClassPathResource("applicationContext.xml"); DefaultListableBeanFactory factory= new DefaultListableBeanFactory (); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(res); //如果用factory好像不行 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); Employee employee= (Employee) act.getBean("employee") ; employee.signIn(); } }
结果
六月 27, 2015 12:14:27 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
六月 27, 2015 12:14:28 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1b1a17a: startup date [Sat Jun 27 12:14:28 CST 2015]; root of context hierarchy
六月 27, 2015 12:14:28 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
logAround开始:现在时间是:Sat Jun 27 12:14:28 CST 2015
logBefore:现在时间是:Sat Jun 27 12:14:28 CST 2015
lsj已经签到
logAround结束:现在时间是:Sat Jun 27 12:14:28 CST 2015
logAfter:现在时间是:Sat Jun 27 12:14:28 CST 2015
一些注意的知识
1.环绕方法通知,环绕方法通知要注意必须给出调用之后的返回值,否则被代理的方法会停止调用并返回null,除非你真的打算这么做。
2.只有环绕通知才可以使用JoinPoint的子类ProceedingJoinPoint,个 连接点类型可以调用代理的方法,并获取、改变返回值。