切面(Aspect):
通常在目标方法执行前后需要执行的方法(如事务、日志、权限),这些方法我们封装到一个类里面,这个类就叫切面。
连接点(joinpoint)
spring里面的连接点指需要切入的方法,通常这个joinpoint可以作为一个参数传入到切面的方法里面(非常有用的一个东西)。
通知(Advice)
通知就是切面里面方法的具体实现,分为前置、后置、最终、异常环绕通知。
切入点(Pointcut)
所谓切入点,通常是指一个表达式,按照包的匹配来切入进去。
目标对象(target)
代理的目标对象。
以下是spring aop的一个实现
先写切面类,代码如下:
public class AopDemo {
public void beforeAdvice(){
System.out.println("我是前置通知");
}
/*
* 如果目标方法发生异常,则后置通知不会执行
*/
public void afterReturnAdvice(){
System.out.println("我是后置通知");
}
/*
* 如果目标方法发生异常,则最终方法还是会执行
*/
public void afterAdvice(JoinPoint joinPoint){
System.out.println(joinPoint.getTarget());//可以获取到目标对象
System.out.println(joinPoint.getArgs()[0]);//获取目标方法的参数
System.out.println("我是最终通知");
}
/*
* 如果发生异常才执行此方法,否则不执行
*/
public void exceptionAdvice(){
//实际的时候如果发生异常,可以跳转错误页面,也可以发邮件给管理员告知出了异常
System.out.println("我是异常通知");
}
public void aroundAdvice(){
//
System.out.println("我是环绕通知");
}
}
然后写业务逻辑类:
public class GoodsImpl {
public void save(Goods goods){
System.out.println("save goods");
}
public void delete(Goods goods){
System.out.println("delete goods");
}
}
配置文件代码:
<!--业务逻辑类 -->
<bean id="goodsImpl" class="com.alt.bean.GoodsImpl"/>
<!-- 切面 -->
<bean id="aop" class="com.alt.aop.AopDemo"/>
<aop:config>
<aop:aspect ref="aop">
<aop:after method="afterAdvice" pointcut="execution(* com.alt.bean.GoodsImpl.save(..))"/>
</aop:aspect>
</aop:config>
最后的测试类:
public class AopTest {
private static ClassPathXmlApplicationContext context = null;
private static GoodsImpl goodsImpl = null;
@BeforeClass
public static void init(){
context = new ClassPathXmlApplicationContext("applicationContext-*.xml");
goodsImpl = (GoodsImpl) context.getBean("goodsImpl");
}
@Test
public void testAop(){
System.out.println("start");
Goods goods = new Goods(1, "大米", 23.4);
goodsImpl.save(goods);
}
}
以上是一个AOP的一个大致实现。
最后关于切入表达式:
execution()里面的内容
execution( [修饰符] 返回值类型 [类的全限定名.]方法名(参数) )