一、Spring IOC
为使用Spring IoC容器,应用代码可以通过下面两个接口完成:
1.BeanFactory。当应用创建BeanFactory实例时,实际上是完成了JavaBean的实例化、配置以及管理。
 Resource resource = new ClassPathResource("appcontext.xml");
 BeanFactory factory = new XmlBeanFactory(resource);
 HelloWord hw = (HelloWorld)factory.getBean("fileHelloWorld");
  
 appcontext.xml的部分内容如下示例:
 1  <beans>
 2   <bean name="hello" class="com.taiji.HelloWorld">
 3   <property name='hello'>
 4     <value>I love you!</value>
 5   </property>
 6   <property name='person'>
 7     <ref bean="person" />
 8   </property
 9   </bean>
10   <bean name="person">
11 <property name='name'>
12     <value>Liu</value>
13   </property>
14   <property name='age'>
15     <value>25</value>
16   </property
17 </bean>
18  </beans>
  
2.ApplicationContext。继承于BeanFactory,主要用于J2EE开发,也是Spring推荐使用的接口。对于Web应用而
言,当J2EE Web应用部署并启动时,Spring
ApplicationContext将会自动被实例化。通过ContextLoaderServlet和ContextLoaderListener能
够自动创建ApplicationContext实例,开发者也可以手动创建。对于struts,采用PlugIn的方式加载是一个非常好的方式。见前面
的struts和spring的整合方案。
那么Spring是怎么做到IOC的呢?Java的反射即可实现IOC机制,通过反射可以生成对象实例,并且通过调用其set方法设置对象的属性:
public static Object newInstance(String className) {
  Class<?> cls = null;
  Object obj = null;
  try {
   cls = Class.forName(className);
   obj = cls.newInstance();
  } catch (ClassNotFoundException e) {
   throw new RuntimeException(e);
  } catch (InstantiationException e) {
   throw new RuntimeException(e);
  } catch (IllegalAccessException e) {
   throw new RuntimeException(e);
  }
  return obj;
 }
public static void setProperty(Object obj, String name, String value) {   
            Class<? extends Object> clazz = obj.getClass();   
            try {   
                String methodName = returnSetMthodName(name);   
                Method[] ms = clazz.getMethods();   
                for (Method m : ms) {   
                    if (m.getName().equals(methodName)) {   
                        if (m.getParameterTypes().length == 1) {   
                            Class<?> clazzParameterType = m.getParameterTypes()[0];   
                            setFieldValue(clazzParameterType.getName(), value, m,   
                                    obj);   
                            break;   
                        }   
                    }   
                }   
            } catch (SecurityException e) {   
                throw new RuntimeException(e);   
            } catch (IllegalArgumentException e) {   
                throw new RuntimeException(e);   
            } catch (IllegalAccessException e) {   
                throw new RuntimeException(e);   
            } catch (InvocationTargetException e) {   
                throw new RuntimeException(e);   
            }   
    }  
 
IOC不难吧,你也可以做一个IOC框架哦?
二、Spring AOP
Spring的AOP要复杂一些,不是仅仅搞个反射就能解决的。AOP最简单的实现机制就是JAVA的动态代理。
动态代理在调用真正的业务类方法之前或之后都插入了代码,这就是JDK的动态代理做的事情,如下是一个动态代理的例子:
public interface Action {
void method();
}
public class ActionImpl  implements Action
{
   public void mothod() {
   System.out.println("Action!");
 }
}
public class MyInvocationHandler implements InvocationHandler {
private Object obj;
public MyInvocationHandler(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Before Action");
Object returnObject = method.invoke(obj, args);
System.out.println("After Action.");
return returnObject;
public static void main(String[] args) throws InterruptedException,
IllegalArgumentException, SecurityException,
InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
//实现业务逻辑的类
ActionImpl a = new ActionImpl();
//JDK创建的动态逻辑类,调用上面的构造函数注入
MyInvocationHandler myInvocation = new MyInvocationHandler(a);
//建业务逻辑类的动态代理类
Object proxy = Proxy.newProxyInstance(ActionImpl.class.getClassLoader(), 
       ActionImpl.class.getInterfaces(), myInvocation);
//业务类自己调用运行代理对象
Action action = (Action) proxy;
    action.method();
}
}
运行后会打印出:
Before Action.
Action!
After Action.
Java的动态代理有一个缺陷,它代理的类必须有一个接口类,否则就不能实现动态代理。在面向接口的编程里面,也许不会有问题,但是事情总是有特殊,那如何实现呢?在Spring中是通过CGLIB来实现的。CGLIB可以直接对类进行增强。如下代码对一个类进行增强:
public class MyClass {
 
    public void method() {
        System.out.println("MyClass.method()");
    }
}
import java.lang.reflect.Method;
 
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
 
public class Main {
 
    public static void main(String[] args) {
 
        Enhancer enhancer = new Enhancer();
 
        enhancer.setSuperclass(MyClass.class);
        enhancer.setCallback( new MethodInterceptorImpl() );
 
 
        MyClass my = (MyClass)enhancer.create();
 
        my.method();
    }
}
class MethodInterceptorImpl implements MethodInterceptor {
        
        public Object intercept(Object obj, 
                                Method method, 
                                Object[] args, 
                                MethodProxy proxy) throws Throwable {
 
            System.out.println(method);
 
            proxy.invokeSuper(obj, args);
 
            return null;
        }
}
执行结果:
public void MyClass.method()
MyClass.method()
可以看到通过CGLIB实现类方法的增加并不比动态代理复杂。当然Spring中需要考虑的东西更多,具体可以研究org.springframework.aop.framework.Cglib2AopProxy.java,实现起来更复杂。这里只是浅析,有助于理解吧。