一、AOP
1.1 AOP的引入
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("----> 获取连接,开启事务");
System.out.println("DB 保存");
System.out.println("----> 事务提交/关闭");
}
}
关注点代码:就是指重复执行的代码
业务代码:核心业务代码。
业务代码与关注点代码分离,好处?
1.关注点代码写一次即可;
2.开发者只需要关注核心业务;
3.运行时期,执行核心业务代码时候动态植入关注点代码; 【代理】
为什么引入AOP?
1.关注点代码,即重复代码,严重影响开发者开发效率
2.关注点代码造成代码比较冗杂。
3.AOP可以实现关注点代码与业务代码的分离。且关注点代码只需写一次即可。
1.2 AOP的概念
AOP,面向切面编程。
功能: 让关注点代码与业务代码分离!
关注点:
关注点代码即重复代码。
切面:
关注点形成的类,即重复代码形成的类,就叫切面(类)!
面向切面编程:
就是指对重复的代码抽取,
在业务方法运行时期动态植入“切面类代码”,即重复代码。
切入点:
通过切入点表达式,可以指定拦截哪些类的哪些方法。
给指定的类在运行时期动态植入切面类代码。
二、手动实现AOP切面编程
2.1 原始代码
原始代码,即重复代码与核心业务代码没有分离。
>>>>>> UserDao.java
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("----> 获取连接,开启事务");
System.out.println("DB 保存");
System.out.println("----> 事务提交/关闭");
}
}
2.2 抽取关注点代码,手动调用关注点代码
将重复代码抽取出来,放在一个类中。在调用业务代码时,进行手动调用。
>>>>>> Aop.java
public class Aop {
public void begin() {
System.out.println("开启事务");
}
public void end() {
System.out.println("关闭事务");
}
}
>>>>>> UserDao.java
public class UserDao implements IUserDao{
private Aop aop;
public void setAop(Aop aop) {
this.aop = aop;
}
@Override
public void save() {
aop.begin();
System.out.println("DB 保存");
aop.end();
}
}
>>>>>> applicationContext.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"
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">
<bean id="aop" class="org.jsoft.d_proxy_e_myaop.Aop"></bean>
<bean id="userDao" class="org.jsoft.d_proxy_e_myaop.UserDao" >
<property name="aop" ref="aop" ></property>
</bean>
</beans>
2.2 抽取关注点代码,工厂代理植入关注点代码
上一步骤,虽然把关注点代码抽取出来了,
但是每次植入关注点代码时,都需要手动调用,这样是比较麻烦。
所以引入了代理工厂,动态植入关注点代码。
>>>>>> Aop.java
public class Aop {
public void begin() {
System.out.println("开启事务");
}
public void end() {
System.out.println("关闭事务");
}
}
>>>>>> UserDao.java
public class UserDao implements IUserDao{
private Aop aop;
public void setAop(Aop aop) {
this.aop = aop;
}
@Override
public void save() {
aop.begin();
System.out.println("DB 保存");
aop.end();
}
}
>>>>>> ObjectFactory .java
public class ObjectFactory {
private static Object target;
private 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 result = method.invoke(target, args);
aop.end();
return result;
}
});
}
}
>>>>>> applicationContext.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"
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">
<bean id="userDao" class="org.jsoft.d_proxy_e_myaop_2.UserDao"></bean>
<bean id="myAop" class="org.jsoft.d_proxy_e_myaop_2.Aop"></bean>
<bean id="userDao_proxy" class="org.jsoft.d_proxy_e_myaop_2.ObjectFactory" factory-method="getInstance">
<constructor-arg index="0" ref="userDao"></constructor-arg>
<constructor-arg index="1" ref="myAop"></constructor-arg>
</bean>
</beans>
>>>>>> App.java
public class App {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/d_proxy_e_myaop_2/applicationContext.xml");
IUserDao proxy =(IUserDao) ac.getBean("userDao_proxy");
proxy.save();
}
}