【概念】
AOP:面向切面编程,是OOP扩展和延伸,解决OOP中一些问题而出现。AOP采用叫做横向抽取机制取代传统方式纵向继承体系对程序扩展和延伸。可以不修改程序源代码,对程序进行扩展,主流应用:权限校验,日志记录,事务管理,性能检测。
【Spring底层原理】
Jdk动态代理:对实现了接口的类才可以产生代理。
<span style="font-size:14px;">public class JdkProxy {
private UserDao userDao;
public JdkProxy(UserDao userDao) {
this.userDao = userDao;
}
public UserDao createProxy(){
UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
if(method.getName().equals("save")){
System.out.println("权限校验===========");
return method.invoke(userDao, args);
}
return method.invoke(userDao, args);
}
});
return proxy;
}
}</span>
【Spring使用】
引入aop约束:
<span style="font-size:14px;"><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" 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.xsd">
</span>
将类配置到Spring中:
<span style="font-size:14px;"> <bean id="customerDao" class="com.itheima.aop.demo3.CustomerDaoImpl"></span>
编写切面类:
public class MyAspectXml {
public void checkPrivilege(){
System.out.println("权限校验=========");
}
public void writelog(){
System.out.println("日志记录=========");
}
/**
* 前置通知
* @param joinPoint
*/
public void before(JoinPoint joinPoint){
System.out.println("前置通知========="+joinPoint);
}
/**
* 后置通知
*/
public void afterReturing(Object result){
System.out.println("后置通知========"+result);
}
/**
* 环绕通知
* @throws Throwable
*/
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("方法前通知=======");
Object obj = joinPoint.proceed();
System.out.println("方法后通知=======");
return obj;
}
/**
* 异常抛出通知:
*/
public void afterThrowing(Throwable ex){
System.out.println("异常抛出通知======"+ex.getMessage());
}
/**
* 最终通知:
*/
public void after(){
System.out.println("最终通知=========");
}
}
配置切面类:
<span style="font-size:14px;"><!-- 切面类 -->
<bean id="myAspectXml" class="com.itheima.aop.demo3.MyAspectXml">
</bean></span>
引入目标类:
<span style="font-size:14px;"><!-- 目标类 -->
<bean id="customerDao" class="com.itheima.aop.demo3.CustomerDaoImpl">
</bean></span>
实体Dao:
<span style="font-size:14px;">public interface CustomerDao {
public void save();
public void find();
public void update();
public String delete();
}</span>
实体DaoImpl:
<span style="font-size:14px;">public class CustomerDaoImpl implements CustomerDao {
public void save() {
System.out.println("保存客户....");
}
public void find() {
System.out.println("查询客户");
//int d=1/0;
}
public void update() {
System.out.println("修改客户...");
}
public String delete() {
System.out.println("删除客户...");
return "aaa";
}</span>
配置Spring的AOP:
<!-- 配置Spring的aop -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.itheima.aop.demo3.*.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* com.itheima.aop.demo3.*.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* com.itheima.aop.demo3.*.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* com.itheima.aop.demo3.*.find(..))" id="pointcut4"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="writelog" pointcut-ref="pointcut2"/>
<aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"/>
<aop:around method="around" pointcut-ref="pointcut3"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
执行代码:
<span style="font-size:14px;">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo4 {
@Resource(name="customerDao")
private CustomerDao customerDao;
@Test
public void demo1(){
customerDao.find();
customerDao.update();
customerDao.save();
customerDao.delete();
}
}</span>
运行结果:
【小结】
Spring的AOP编程挺实用的,它可以对方法进行批量增强操作。符合OCP(开放封闭原则)。