Spring(2)之 (2.1 Spring AOP 开发)

在Spring AOP编程中:

如果加入容器中的目标对象有实现接口,用 JDK代理;
如果目标对象没有实现接口,用 Cglib代理;

手动实现 AOP编程:

AOP面向切面编程: AOP业务代码与关注点代码分离;
关注点: 重复的代码方法)叫关注点;
切面: 关注点形成的类叫切面类;
AOP: 关注点代码只写一次;
       开发者只需要关注核心代码;
       运行时,执行核心业务代码,动态植入关注点代码【用代理类】

1. 没有用代理类时,直接在实现类即目标对象中添加代码——》将代码提取出来形成方法——》将重复代码形成的方法提取出来形成类,再在目标类的业务代码前后调用生成的类对象中的关注点代码(所以要想调用关注点代码形成的类中的方法,目标类中就要有相对应的对象属性):目标对象中要用到 MyAop类对象 aop,用注解生成,所以 MyAop.java类添加 @Component注解自动形成对象;再注入进目标对象,所以类中属性 aop前添加@Resource注解将容器中生成的 MyAop 对象aop注入进来;再在业务代码前后调用对象 aop中的方法(中的关注点代码); 测试类中最终要调用目标对象中的方法,要得到目标类的 bean对象 userDao,所以 UserDao.java类上添加@Component(“userDao”)注解在容器中生成 userDao对象。
1.1 IUserDao.java
(接口中有一个 save方法)

public interface IUserDao{
	public void save() throws Exception;
}

1.2 UserDao.java(目标对象提取成单独类之前:)
(直接在实现类即目标对象中添加代码——》将重复代码提取出来形成方法——》将重复代码形成的方法提取出来形成类)

public class UserDao implements IUserDao{
	public void save() throws Exception{
		//System.out.println("开始事务"); //关注点代码(开始事务)
		beginTrans();     //业务代码
		System.out.println("----数据已保存----"); //关注点代码(提交事务)
		commitTrans();
		//System.out.println("提交事务"); //提交事务
	}
	
	public void beginTrans(){
		System.out.println("开始事务");
	}
	public void commitTrans(){
		System.out.println("提交事务");
	}
}

1.2 UserDao.java(目标对象提取成单独类之后:)
(UserDao中要用到 aop对象,用注解生成,所以 MyAop.java类添加 @Component注解自动形成对象;再注入进来,所以类中 aop前添加@Resource注解将容器中生成的 MyAop 对象aop注入进来;再在业务代码前后调用对象 aop中的方法;)

@Component("userDao")
public class UserDao implements IUserDao{
        @Resource
	private MyAop aop;
	public void save() throws Exception{	
		aop.beginTrans();
		System.out.println("----数据已保存----");
		aop.commitTrans();
	}
}

1.3 MyAop.java
(目标对象提取后形成的单独类)

@Component
public class MyAop{
	public void beginTrans(){
		System.out.println("开始事务");
	}
	public void commitTrans(){
		System.out.println("提交事务");
	}
}

1.4 bean.xml
(IOC容器用注解自动生成bean对象之前开启Spring扫描)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- base-package扫描包即子包下的类 -->
    <context:component-scan base-package="com.asd.myaop"></context:component-scan>
    
</beans>

Test.java
(要用到 UserDao的 bean对象userDao,所以 UserDao.java类上添加@Component注解;)

public class Test{
	public static void main(String[] args) {
		ApplicationContext applicationContext=new ApplicationContext("bean.xml");
		IUserDao userDao=(IUserDao)applicationContext.getBean("userDao");
		try{
			userDao.save();
		}catch(Exception e){
			e.printStackTrace();
		}				
	}
}

运行结果:
在这里插入图片描述

2. 手动实现利用代理工厂实现AOP
(① ProxyFactory.java类中有两个属性:private static Object target; private static MyAop aop;:目标对象、myAop对象,所以在对应的两个类上分别用@Component(“userDao”)注解生成对应的两个 bean对象; ② 在 bean1.xml中利用静态方法生成对应bean对象 userProxy,且将两个属性注入;③ Test.java中得到 userProxy的 bean对象,调用其 save方法;)
2.1 IUserDao.java

public interface IUserDao{
	public void save() throws Exception;
}

2.2 UserDao.java(目标对象)

@Component("userDao")
public class UserDao implements IUserDao{
	public void save() throws Exception{	
		System.out.println("----数据已保存----");
	}
}

2.3 MyAop.java
(目标对象提取后形成的单独类)

@Component
public class MyAop{
	public void beginTrans(){
		System.out.println("开始事务");
	}
	public void commitTrans(){
		System.out.println("提交事务");
	}
}

2.4 ProxyFactory.java

public class ProxyFactory{
	//目标对象
	private static Object target;
	private static MyAop aop;
	//代理对象
	public static Object getProxyFactory(Object _target,MyAop _aop){
		target _target;
		aop _aop;
		return Proxy.newProxyInstance(
			target.getClass().getClassLoader(),
			target.getClass.getInterfaces(),
			new InvocationHandler(){
				public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
					aop.beginTrans();
					Object resultValue=method.invoke(target,args);
					aop.commitTrans();
					return resultValue;
				}
			}
		);
	}	
}

2.5 bean1.xml
(ProxyFactory类中 getProxyFactory是静态方法,ref 引用 IOC容器中已经生成的 userDao对象(UserDao.java类上@Component(“userDao”)注解生成),)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- base-package扫描包即子包下的类 -->
    <context:component-scan base-package="com.asd.myaop1"></context:component-scan>
    
    //ProxyFactory类中 getProxyFactory是静态方法
    <bean id="userProxy" class="com.asd.myaop1.ProxyFactory" factory-method="getProxyFactory">
  	<constructor-arg index="0" ref="userDao"></constructor-arg>
  	<constructor-arg index="1" ref="myAop"></constructor-arg>
    </bean>
    
</beans>

Test.java

public class Test{
	public static void main(String[] args) {
		ApplicationContext applicationContext=new ApplicationContext("bean1.xml");
		IUserDao proxy=(IUserDao)applicationContext.getBean("userProxy");
		try{
			proxy.save();
		}catch(Exception e){
			e.printStackTrace();
		}				
	}
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41029923/article/details/84230164