Spring初体验

    Hibernate之后就迎来了Spring, ^_^  ^_^  不过此处据说是让人看不到春天的。

     Spring框架的特点:

    1、 黏合剂: 面向组件开发的技术, Spring提供了对已有的各种组件技术的融合。

   2、 轻量级的框架: 指应用程序基于框架开发依赖于API的严重程度低(这样子学习成本低 且 便于框架更换)。

          都说学习Spring没什么新东西, 主要的就是学习一些思想。 因此今天我便开始学习了IOC思想。

         IOC降低了面向对象编程对象之间的耦合度, 学习IOC主要要注意两个方面的问题:

        a、 控制什么: 对象之间的依赖关系是什么

       b、 反转到哪里

     ————IOC容器主要做了两项工作:

    a、 创建对象

   b、 根据对象之间的依赖关系进行注入——使用属性的get()/set()方法 或者使用构造函数。

   

   重点是applicationContext.xml文件的配置, 多练习....



  Spring & AOP ——————面向切面编程

  切面: 和业务逻辑的核心实现没有关系, 但业务逻辑的实现需要某个领域提供相应的服务(如炒菜与洗菜,刷锅)。

   在学习AOP时重点提到了代理模式: 代理模式的用途在于为真正的对象提供一个服务。

   代理模式又分为静态代理与动态代理, 静态代理只为某一种对象提供服务, 而动态代理可以为不同类型接口类型的对象提供服务。

   代理模式中存在三种角色, 分别是  真实对象、 代理对象、 一个真实对象和代理对象的接口

  ——————————————如下贴出我写的AOP练习 (以  洗菜——炒菜——洗碗 为例)

    A、 不使用代理模式:

   public class Worker {

public void beforeWork()
{
  System.out.println("炒菜准备工作");
}

public void doWork()
{
  beforeWork();
  System.out.println("正在炒菜.....");
  afterWork();
}

public void afterWork()
{
  System.out.println("洗碗工作");
}
}
    不使用代理模式有一个很大的弊端就是每次炒菜时都得重复地调用beforeWork()与afterWork()方法, 这样子造成了代码冗余

B、 使用静态代理模式:

       CookInterface.java  ——真实对象与代理对象的共同接口

   public interface CookInterface {

public void doCooking();

}

    CookImpl.java   ——真实对象, 实现炒菜这个核心业务

   public class CookImpl implements CookInterface{

public void doCooking() {
  System.out.println("正在炒菜....");
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 
}


CookProxy.java   ——代理对象

  public class CookProxy implements CookInterface{ //代理对象与真实对象实现同一个接口

CookInterface cooker;

public CookInterface getCooker() {
  return cooker;
}

public void setCooker(CookInterface cooker) {
  this.cooker = cooker;
}

public void doCooking() {
  beforeWork();
  cooker.doCooking();
  afterWork();
}

/**
  * 将为核心业务服务的方法抽取到代理对象中
  *
  */
public void beforeWork(){
  System.out.println("洗菜");
}

public void afterWork(){
  System.out.println("洗碗");
}

}



TestAop.java   ——测试类

public class TestAop {

public static void main(String[] args) {
  CookInterface cooker = new CookImpl();
  CookProxy cookerProxy = new CookProxy();
  cookerProxy.setCooker(cooker);
  cookerProxy.doCooking();
}

}

    静态代理模式虽然减少了代码冗余, 但是其只能为实现某一种类型接口的特定对象提供服务



C、 动态代理:  (动态代理类与测试类发生了变化, 其他两个类同上)

     CookDynamicProxy.java ——动态代理类

   /**
* 为不同接口类型的对象动态产生代理对象
* @author Administrator
*
*/
public class CookDynamicProxy implements InvocationHandler{

private Object targetObject; //真实对象
/**
  * 动态产生代理对象
  */
public Object createProxyObject(Object targetObject){
  this.targetObject = targetObject;
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
    targetObject.getClass().getInterfaces(), this);
 
}

/**
  * 提供代理的服务(切面)
  * proxy是代理对象
  * method是代理对象调用的方法
  * args是调用方法的实参列别
  */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  beforeWork();
  //调用真实对象的方法
  Object result = method.invoke(targetObject, args);
  afterWork();
  return result;
}

public void beforeWork(){
  System.out.println("洗菜");
}

public void afterWork(){
  System.out.println("洗碗");
}

}



TestDynamicProxy.java

public class TestDynamicProxy {

public static void main(String[] args) {
  CookInterface cooker = new CookImpl();
  CookInterface cookerProxy = (CookInterface)new CookDynamicProxy().createProxyObject(cooker);
  cookerProxy.doCooking();
}

}

这样子就与具体的接口解耦了。 ^_^  ^_^  这是一种比较好的做法。



D、 在Spring中使用动态代理模式, 通过配置appicationContext.xml以及调用Spring API的方式实现

       这种方式主要是配置applicationContext.xml, 如下是我的配置:

     <!-- 配置真实对象 -->
   <bean id="realWorker" class="cn.com.aop.CookImpl"></bean>
   <!-- 配置通知 -->
   <bean id="arroundNote" class="cn.com.aop.ArroundLog"></bean>
    <!-- 配置动态代理 -->
    <bean id="workProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 指定要实现的接口 -->
    <property name="interfaces"><value>cn.com.aop.CookInterface</value></property>
    <!-- 指定代理的真实对象 -->
    <property name="target" ref="realWorker"></property>
    <!-- 指定运行时织入的通知 -->
    <property name="interceptorNames">
    <list>
    <value>arroundNote</value>
    </list>
    </property>
    </bean>

   关于源文件只有如下两个与上面的源文件不同, 列举如下:

   ArroungLog.java   ——通知

  /**
* 切面代码,在方法的前后进行织入
* @author Administrator
*
*/
public class ArroundLog implements MethodInterceptor {

public Object invoke(MethodInvocation arg0) throws Throwable {
  beforeWork();
  Object result = arg0.proceed();
  afterWork();
  return result;
}

public void beforeWork(){
  System.out.println("洗菜");
}

public void afterWork(){
  System.out.println("洗碗");
}
}

Test.java  ——测试类

public class Test {
public static void main(String[] args) {
  Resource resource = new ClassPathResource("applicationContext.xml");
  BeanFactory bf = new XmlBeanFactory(resource);
  CookInterface cooker = (CookInterface)bf.getBean("workProxy");
  cooker.doCooking();

 
}

}

你可能感兴趣的:(spring,AOP,编程,框架,IOC)