您的位置:首页 > 编程语言 > Java开发

spring之手动实现AOP编程

2018-01-22 21:26 429 查看

前言

首先来看如何手动实现简单AOP编程的例子,对于掌握spring的核心AOP编程有很大的帮助。

AOP编程

简单说一下概念,AOP是面向切面编程。利用AOP可以实现“业务代码”与“关注点代码”分离。业务代码就是平时程序员最关注的核心业务代码,而关注点代码是程序员不怎么关心的,或者可以通过框架来帮我们实现在运行时期动态的植入到我们的核心业务代码中去,也就是说程序员开发中可以不用花大量精力关注这些,只要会配置即可。一般的“关注点”代码为实现事务管理,日志管理,异常处理等非核心业务代码。

手动实现AOP

比如,在数据库操作代码中,添加事务管理不应该是程序员关注的点,程序员只需要关心主要的业务,下面代码是保存数据到数据库中,程序员只需要关心核心业务save(user),也就是这一行代码,事务直接交给“其他人”去做,这个人就是spring核心AOP。

// 保存一个用户
public void add(User user) {
Session session = null;
Transaction trans = null;
try {
session = HibernateSessionFactoryUtils.getSession();   // 【关注点代码】
trans = session.beginTransaction();    // 【关注点代码】

session.save(user);     // 核心业务代码

trans.commit();     //…【关注点代码】

} catch (Exception e) {
e.printStackTrace();
if(trans != null){
trans.rollback();   //..【关注点代码】

}
} finally{
HibernateSessionFactoryUtils.closeSession(session);   ////..【关注点代码】

}
}


上面代码为静态的也就是编译时期添加事务,那么能不能在运行时期植入事务代码呢?这就是AOP编程的核心思想。即使用动态代理实现在运行时期动态植入通用的代码,来达到目的。

那么业务代码与关注点代码分离的好处是:

(1)关注点代码写一次即可;

(2)开发者只需要关注核心业务;

(3)运行时期,执行核心业务代码时候动态植入关注点代码;

动态代理实现简单AOP编程

需要先导入spring核心jar包。模拟:事务管理,保存用户。

public interface IUserDao {

public void save();
}


@Component
public class UserDao implements IUserDao {

@Override
public void save() {
System.out.println("保存用户信息。。。");

}

}


@Component
public class Aop {

public void begin() {
System.out.println("开启事务!");
}

public void commit() {
System.out.println("提交事务!");
}

}


@Component
public class ProxyUserDao {
static Object target;
static Aop aop;

public static Object getInstance(Object target_, Aop aop_) {
target = target_;
aop = aop_;
return Proxy.newProxyInstance(target_.getClass().getClassLoader(),
target_.getClass().getInterfaces(), new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
aop.begin();
Object returnValue = method.invoke(target, args);
aop.commit();
return returnValue;
}
});
}

}


测试:

public class App {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"edu/test/aop/bean.xml");

@Test
public void testApp() {
IUserDao userDao = (IUserDao) ac.getBean("userDao_proxy");
userDao.save();
}

}


打印结果如下:



bean.xml配置

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 
<!-- 调用工厂静态创建userDao -->
<bean id="userDao_proxy" class="edu.test.aop.ProxyUserDao" factory-method="getInstance">
<constructor-arg index="0" ref="userDao" ></constructor-arg>
<constructor-arg index="1" ref="aop" ></constructor-arg>
</bean>

<!-- 开启注解扫描 -->
<context:component-scan base-package="edu.test.aop"></context:component-scan>

</beans>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring aop 手动实现AOP