概念方面
一般用于要增加新的功能的时候使用AOP,例如日志,事务等
切面:要增加的aspect,这里相当于一个类
切入点:哪些类的方法需要被切入
通知、增强:切面中的方法
具体实现
这里首先要了解动态代理模式,真实角色和代理角色要实现同一个接口,代理角色代理真实角色,静态代理会显式地定义代理对象,而动态代理会在运行期间创建代理对象
1、抽象类
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
2、真实角色
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("add");
}
public void delete() {
System.out.println("delete");
}
public void update() {
System.out.println("update");
}
public void select() {
System.out.println("select");
}
}
3、我们这里想向UserServiceImpl中的每个方法增加一下两个日志模块
这里首先使用Spring的API实现
public class BeforeLog implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName()+"的"+method.getName()+"方法被执行了");
}
}
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object resultValue, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("执行了"+method.getName()+"方法,返回值为"+resultValue);
}
}
首先在XML往Spring容器中注入bean
<bean id="userService" class="com.lu.service.UserServiceImpl"/>
<bean id="beforeLog" class="com.lu.log.BeforeLog"/>
<bean id="afterLog" class="com.lu.log.AfterLog"/>
再往切入点切入通知
<aop:config>
<!--切入点:UserServiceImpl的所有方法都切入-->
<aop:pointcut id="pointcut" expression="execution(* com.lu.service.UserServiceImpl.*(..))"/>
<!--通知 advice-ref=被切入的对象 pointcut-ref=往哪个点切入-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
测试类
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=context.getBean("userService", UserService.class);
userService.add();
userService.delete();
userService.update();
userService.select();
}
我们还可以自定义切面
public class DiyAspect {
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
}
配置文件
<bean id="diyAspect" class="com.lu.DiyAspect"/>
<aop:config>
<aop:aspect ref="diyAspect">
<aop:pointcut id="pointcut" expression="execution(* com.lu.service.UserServiceImpl.*(..))"/>
<!--method:切面里的通知 pointcut-ref:切点-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>