学了IOC之后,紧跟着就是AOP(面向切面编程)
来个官方一点的,面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
简单举个例子来说,我们通过java代码对数据库进行增删改操作的时候,需要对事务进行控制,我们阻止事务的自动提交,事务成功后手动提交以及失败后回滚事务的一系列操作是必须的,这样就需要做大量重复的工作,而AOP就可以帮助我们解决这个问题。简单的代码描述一下这个过程(Spring)。
//接口
inteface UserService{
void reg();
}
//实现类
public class UserServiceImpl implements UserService{
@Override
public void reg() {
System.out.println("数据添加成功!");
}
}
上面是事务层的代码
下面编写一下AOP的相关代码(额外功能的代码)
//实现aop中的方法拦截器
public class MyAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("开始事务");
//调用service中的方法(在spring中通过配置文件将它们关联起来)
Object o=mi.proceed();
System.out.println("结束事务");
return o;
}
}
下面看一下怎么配置
<!--配置目标类-->
<bean id="userService" class="com.service.impl.UserServiceImpl"></bean>
<!--配置额外的功能代码-->
<bean id="myAdvice" class="com.advice.MyAdvice"></bean>
<!--aop相关的配置-->
<aop:config>
<!--切入点-->
<aop:pointcut id="pt" expression="execution(* com.service..*.*(..))"></aop:pointcut>
<!--在切入点切入额外的功能代码-->
<aop:advisor advice-ref="myAdvice" pointcut-ref="pt"></aop:advisor>
</aop:config>
上面的代码中我们先写了目标类,就是我们的sevice里面的代码,里面包含了reg()注册方法,注册方法的主要流程应该是添加数据到数据库,但是我们需要给添加方法加上事务的提交回滚等操作,这些操作因为了aop所以我们可以写在MyAdvice类中,需要继承的是MethodInterceptor这个方法拦截器,实现其中的invoke方法,其中mi.proceed()方法的返回值和service中的reg方法的返回值相同,再通过xml的配置,我们就完成了这个功能的增强。
测试一下
public class TestAop {
public static void main(String[] args) {
//创建spring的工厂对象帮助我们创建对象
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
//获取我们需要的对象(这里必须要用接口引用,因为底层使用了动态代理技术,实际获取的不是service的实现类)
UserService us=(UserService) ac.getBean("userService");
//调用方法
us.reg();
}
}
运行结果