Spring Chapter 2 AOP 配置&代理的方法

<!--
	Spring Chapter 2:代理&Spring中的代理
-->

首先,我们昨天说了Spring中最求的是面向接口编程,这样就减少了各种代码之间的耦合性,
大大增强了程序运行的性能!
今天呢,主要是讲配置Spring中的代理,来完成面向切面编程!
面向切面:在不改变原有代码的基础上,实现在方法的前面或(和)后面添加其他的方法!

这里只讲两种最常见的:动态代理和Spring代理

一,动态代理
	a)写好我们的接口:
		public interface IUser{
			//添加用户的方法
			public void addUser(UserInfo user);
			//...其他的方法
		}
		
	b)实现该接口的类:
		public class UserDao implements IUser{
			//override
			addUser(UserInfo user){
				//...执行添加用户的代码
				//eg:SessionUtil.getSession().save(user);
			}
		}
	
	c)编写(动态)代理,实现invocationHandler(java.lang.reflect)接口
		public class ObjProxy implements invocationHandler{
			//在这个里面需要一个Object属性
			private Object obj;
			//只需要getter
			public Object getObj(){
				//注意这里,为了达到代理的效果,这就不能直接return this.obj了!而是要采用代理的方法
				return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
			}
			//需要一个构造函数来赋值
			public ObjProxy(Object obj){
				this.obj=obj;
			}
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				//这里开始切入了~,写入需要在目标方法之前执行的方法
				//eg:SessionUtil.beginTran();
				
				//这里是调用本该调用的方法(记住里面的参数)
				Object result=method.invoke(obj,args);
				
				//写入需要在目标方法之后执行的方法
				//eg:SessionUtil.commitTran();
				
				//记住返回值
				return result;
			}
		}
	
	d)这样就查最后一步了~写一个测试的方法
	public MyTest{
		public void static main(String[] args){
			//得到接口对象并调用里面的方法
			IUser user=new ObjProxy(new UserDao()).getObj();
			UserInfo ui=new UserInfo();
			//设置该设置的值...
			//调用该方法
			user.addUser(ui);
			
			//这样就搞定了~
		}
	}
	
二,在Spring中使用代理(配置一次~就完全Happy了)
实现步骤(前面两步相同):
	a)写好我们的接口:
		public interface IUser{
			//添加用户的方法
			public void addUser(UserInfo user);
			//...其他的方法
		}
		
	b)实现该接口的类:
		public class UserDao implements IUser{
			//override
			addUser(UserInfo user){
				//...执行添加用户的代码
				//eg:SessionUtil.getSession().save(user);
			}
		}
		
	c)为了更好的说明这个例子,我就在这里多加一个专门实现方法的类
		public SessionUtil{
			private static SessionFactory sf=null;
			static{
				sf=new Configuration().configure().buildSessionFactory();
			}
			
			public static Session getSession(){
				//要能正常使用getCurrentSession(),就必须要在Hibernate.cfg.xml中配置current_session_context_class,配置实现类为thread类,多线程
				return sf.getCurrentSession();
			}
			
			public void beginTrans(){
				getSession().beginTranscation();
			}
			
			public void commitTrans(){
				getSession().getTranscation().commit();
				getSession().close();
			}
		}
	
	d)在配置文件(applicationContext.xml)中写:
	<beans 
		xmlns="http://www.springframework.org/schema/beans"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
		
		<!-- 目标方法,通俗点,就是那个准备被切的,也是那个实现了接口的类 -->
		<bean id="udao" class="com.shu.dao.impl.UserDao"/>
		
		<!-- 通知(增强),也就是需要在切面执行的方法,也是那个增强方法的所在类 -->
		<bean id="util" class="com.shu.util.SessionUtil"/>
		
		<!-- 开始配置 -->
		<aop:config>
			<!-- 配置切面 -->
			<aop:aspect id="userTest" ref="util">
				<!-- 切入点配置(需要借用到正则表达式) -->
				<aop:pointcut expression="execution(* com.shu.dao.impl.*.*(..))" id="ucut"/>
				<!-- 之前执行的 -->
				<!--method 中写入那个类的哪个方法是你想要的-->
				<aop:before method="beginTrans" pointcut-ref="ucut"/>
				<!-- 之后执行的 -->
				<aop:after method="commintTrans" pointcut-ref="ucut"/>
			</aop:aspect>
		</aop:config>
	</beans>
	
	e)测试:
		public MyTest{
			public static void main(String[] args){
				//按照Spring的方式来创建
				BeanFactory bf=new classPathXmlApplicationContext("applicationContext.xml");
				IUser user=(IUser)bf.getBean("udao(在配置文件中我们的目标的ID)");
				UserInfo ui=new UserInfo();
				//设置值
				user.save(ui);
				//finish~
			}
		}
		
<!--
Author:Lovingshu's Forever
Date:2011-11-22 22:10
Remark:Nothing~but today I cut my hair~short style!
-->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值