本文主要包含spring框架的整个理念。
1.IoC(反转控制)和依赖注入
2.面向方面编程
1.IoC(反转控制)和依赖注入
参考这篇文章:http://www.bccn.net/Article/kfyy/java/jszl/200610/4512.html
使用IoC,对象是被动的接受依赖类,而不是自己主动的去找。容器在实例化的时候主动将它的依赖类注入给它。可以这样理解:控制反转将类的主动权转移到接口上,依赖注入通过xml配置文件在类实例化时将其依赖类注入。
2.面向方面编程
2.1 eclipse中面向方面编程开发环境。
2.2 面向方面编程简介
2.3 一个简单的AOP demo
2.1 eclipse中面向方面编程开发环境
windows -> install new softwares -> add a new website ->输入下面的update site :http://download.eclipse.org/tools/ajdt/36/update -> 选择所有的选项。如图:

点击finish,安装完成之后,重启eclipse,然后新建一个java工程,应该出现下面的效果:

2.2 面向方面简介
在面向对象的编程中,主要是能够解决的是一个对相集合之间的关系,通过继承的策略实现代码的重复使用。但是也存在oo无法解决的问题,当要为没有类层次的对象引入公共行为的话,oo的思想是无法解决的,所以引入了面向方面编程。
面向方面关键概念:
join point:程序执行过程中某一点,advice就是相对于这个join point而言的。
advice : advice是join point的执行代码,都是方面的“执行的逻辑”。
pointcut:一组join point的总称,用于指示某个建议应用于何处。
introduction:为现有的java类添加字段或者是方法。
before advice :在调用join point之前调用before advice。
after advice:和before advice相反。
2.3简单的aop编程实例
2.3.1使用j2se的动态代理实现aop
客户端代码:
/** * */ package aop.proxy; import com.sun.org.apache.bcel.internal.generic.NEW; /** * 传统实现,没有使用aop框架 * @author jefferyxu * */ public class BusinessLogicUsage { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub IBusinessLogic businessLogic = (IBusinessLogic)LoggingProxyAspect.bind(SecurityProxyAspect.bind(new BusinessLogicCoreConcern())); businessLogic.businessMethod1(); System.out.println(); businessLogic.businessMethod2(); } }
BusinessLogicCoreConcern.java
package aop.proxy; /** * 传统的做法 ,没有使用aop框架 * @author jefferyxu * */ public class BusinessLogicCoreConcern implements IBusinessLogic { @Override public void businessMethod1() { // TODO Auto-generated method stub doCoreBusiness1(); } @Override public void businessMethod2() { // TODO Auto-generated method stub doCoreBusiness2(); } /** * 执行核心业务1 */ private void doCoreBusiness1() { System.out.println("doCoreBusiness1"); } /** * 执行核心业务2 */ private void doCoreBusiness2() { System.out.println("doCoreBusiness2"); } }
IBusinessLogic.java
/** * @author jefferyxu */ package aop.proxy; public interface IBusinessLogic { public void businessMethod1(); public void businessMethod2(); }
LoggingProxyAspect.java
/** * */ package aop.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import sun.awt.geom.AreaOp.AddOp; import sun.util.logging.resources.logging; /** * @author jefferyxu * */ public class LoggingProxyAspect implements InvocationHandler{ private Object proxyobj; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub beforeAdvice(method); Object object = method.invoke(proxyobj, args); afterAdvice(method); return object; } public LoggingProxyAspect(Object obj) { this.proxyobj = obj; } /** * 通过动态代理生成动态对象 * @param object * @return */ public static Object bind(Object object) { Class cls = object.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new LoggingProxyAspect(object)); } /** * 调用前处理 * @param method */ private void beforeAdvice(Method method){ logging("before calling : " + method.getName()); } /** * 调用之后处理 * @param method */ private void afterAdvice(Method method) { logging("after calling :" + method.getName()); } private void logging(String str){ System.out.println(str); } }
SecurityProxyAspect.java :
/** * */ package aop.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author xuqiang * */ public class SecurityProxyAspect implements InvocationHandler { private Object proxyobj; /* (non-Javadoc) * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */ @Override public Object invoke(Object arg0, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub /** * 这里只关联到businessMethod1 */ if(method.getName().equalsIgnoreCase("businessMethod1")) { beforeAdvice(method); } Object object = method.invoke(proxyobj, args); return object; } private void beforeAdvice(Method method) { doSecurityCheck(); } private void doSecurityCheck(){ System.out.println("doing security check"); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub } public SecurityProxyAspect(Object obj) { this.proxyobj = obj; } /** * 通过动态代理生成对象代理 * @param object * @return */ public static Object bind(Object object) { Class cls = object.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new SecurityProxyAspect(object)); } }
上面的代码使用的是java中的InvocationHandler实现的。简单的讲: Proxy类的设计用到代理模式的设计思想,Proxy类对象实现了代理目标的所有接口,并代替目标对象进行实际的操作。但这种替代不是一种简单的替代, 这样没有任何意义,代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截。所以,Proxy应该包括一个方法拦截 器,来指示当拦截到方法调用时作何种处理。InvocationHandler就是拦截器的接口。(http://blog.youkuaiyun.com/pizishuai2008/archive/2009/07/28/4385906.aspx)。
也就是当接口的实现类或者是接口调用接口中的函数的时候,java会自动调用invoke(InvocationHandler接口中的一个待实现的函数)函数。默认的情况下,调用接口中的任何一个函数,都会触发invoke函数被调用,但是可以在函数invoke中通过method的名称来做限制,就像上面的做法:
if(method.getName().equalsIgnoreCase("businessMethod1")) { beforeAdvice(method); }
下面是一个简单的使用InvocationHandler实现的例子:
IAnimal.java :
package proxytest; public interface IAnimal { void info(); }
Dog.java :
package proxytest; public class Dog implements IAnimal { public void info() { System.out.println("this is a dog!"); } }
客户端程序:
package proxytest; import java.lang.reflect.*; public class ProxyTest { public static void main(String[] args) throws InterruptedException { final IAnimal animal = new Dog(); Object proxyObj =Proxy.newProxyInstance( animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), /** * 定义当proxyObj对象调用interface的接口时调用 * 的方法 */ new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) { try { System.out.println("被拦截的方法:" + method.getName()); return method.invoke(animal, args); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }); if(proxyObj instanceof IAnimal) { System.out.println("the proxyObj is an animal!"); } else { System.out.println("the proxyObj isn't an animal!"); } if(proxyObj instanceof Dog) { System.out.println("the proxyObj is a dog!"); } else { System.out.println("the proxyObj isn't a dog!"); } IAnimal animalProxy = (IAnimal)proxyObj; //animalProxy.info(); //animalProxy.hashCode(); System.out.println(animalProxy.getClass().getName().toString()); } }
2.3.2使用aspectj来实现上面的demo如下:
客户端程序:
/** * */ package aop.aspectj; import aop.proxy.*; /** * @author jefferyxu * */ public class BusinessLogicUsage { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub IBusinessLogic businessLogic = new BusinessLogicCoreConcern(); businessLogic.businessMethod1(); System.out.println(); businessLogic.businessMethod2(); } }
SecurityAspect.java : 新增加一个aspect

代码如下:
/** * */ package aop.aspectj; import aop.proxy.*; /** * @author jefferyxu * */ public aspect SecurityAspect { private pointcut securityExecution(): execution(public void IBusinessLogic.businessMethod1()); // 声明join point,定义在何时调用函数before和after // 声明before advice before() : securityExecution() { doSecurityCheck(); } private void doSecurityCheck() { System.out.println("doing security check"); } }
TranscationAspect.java :
/** * */ package aop.aspectj; import aop.proxy.*; /** * @author xuqiang * */ public aspect TranscationAspect { /** * 定义切入点 */ private pointcut transcationExecution() : execution(public void IBusinessLogic.businessMethod1()) || execution(public void IBusinessLogic.businessMethod2()); /** * 定义before advice */ before() : transcationExecution() { start(); }; /** * 定义after advice */ after() : transcationExecution() { commit(); } /** * 模拟transacation */ private void start() { System.out.println("transcation start"); } private void commit() { System.out.println("transcation commit"); } }
给整个工程添加aspectj属性:

运行整个工程,完成。
本文介绍Spring框架的核心理念,包括IoC(反转控制)与依赖注入、面向方面编程(AOP)等关键技术。通过实例演示如何使用Java动态代理及AspectJ实现AOP。
1377

被折叠的 条评论
为什么被折叠?



