国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

Spring入門

2019-11-18 16:14:51
字體:
來源:轉載
供稿:網友

SPRing是一個非常優(yōu)秀的輕量級框架,通過Spring的IoC容器,我們的關注點便放到了需要實現(xiàn)的業(yè)務邏輯上。對AOP的支持則能讓我們動態(tài)增強業(yè)務方法。編寫普通的業(yè)務邏輯Bean是非常容易而且易于測試的,因為它能脫離J2EE容器(如Servlet,jsp環(huán)境)單獨進行單元測試。最后的一步便是在Spring框架中將這些業(yè)務Bean以xml配置文件的方式組織起來,它們就按照我們預定的目標正常工作了!非常容易!

本文將給出一個基本的Spring入門示例,并演示如何使用Spring的AOP將復雜的業(yè)務邏輯分離到每個方面中。

1.開發(fā)環(huán)境配置
2.編寫B(tài)ean接口及其實現(xiàn)
3.在Spring中配置Bean并獲得Bean的實例
4.編寫Advisor以增強ServiceBean
5.總結

1.開發(fā)環(huán)境配置

首先,需要正確配置java環(huán)境。推薦安裝JDK1.4.2,并正確配置環(huán)境變量:

JAVA_HOME=<JDK安裝目錄>
CLASSPATH=.
Path=%JAVA_HOME%/bin;……

我們將使用免費的Eclipse 3.1作為IDE。新建一個Java Project,將Spring的發(fā)布包spring.jar以及commons-logging-1.0.4.jar復制到Project目錄下,并在Project > Properties中配置好Java Build Path:

Spring入門(圖一)

點擊查看大圖

2.編寫B(tài)ean接口及其實現(xiàn)

我們實現(xiàn)一個管理用戶的業(yè)務Bean。首先定義一個ServiceBean接口,聲明一些業(yè)務方法:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
/**
 * Interface of service facade.
 *
 * @author Xuefeng
 */
public interface ServiceBean {
    void addUser(String username, String passWord);
    void deleteUser(String username);
    boolean findUser(String username);
    String getPassword(String username);
}

然后在MyServiceBean中實現(xiàn)接口:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 *
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
import java.util.*;
public class MyServiceBean implements ServiceBean {
    private String dir;
    private Map map = new HashMap();
    public void setUserDir(String dir) {
        this.dir = dir;
        System.out.println("Set user dir to: " + dir);
    }
    public void addUser(String username, String password) {
        if(!map.containsKey(username))
            map.put(username, password);
        else
            throw new RuntimeException("User already exist.");
    }
    public void deleteUser(String username) {
        if(map.remove(username)==null)
            throw new RuntimeException("User not exist.");
    }
    public boolean findUser(String username) {
        return map.containsKey(username);
    }
    public String getPassword(String username) {
        return (String)map.get(username);
    }
}


為了簡化邏輯,我們使用一個Map保存用戶名和口令。

現(xiàn)在,我們已經有了一個業(yè)務Bean。要測試它非常容易,因為到目前為止,我們還沒有涉及到Spring容器,也沒有涉及到任何Web容器(假定這是一個Web應用程序關于用戶管理的業(yè)務Bean)。完全可以直接進行Unit測試,或者,簡單地寫個main方法測試:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
public class Main {
    public static void main(String[] args) throws Exception {
        ServiceBean service = new MyServiceBean();
        service.addUser("bill", "hello");
        service.addUser("tom", "goodbye");
        service.addUser("tracy", "morning");
        System.out.println("tom's password is: " + service.getPassword("tom"));
        if(service.findUser("tom")) {
            service.deleteUser("tom");
        }
    }
}

執(zhí)行結果:
Spring入門(圖二)

3.在Spring中配置Bean并獲得Bean的實例

我們已經在一個main方法中實現(xiàn)了業(yè)務,不過,將對象的生命周期交給容器管理是更好的辦法,我們就不必為初始化對象和銷毀對象進行硬編碼,從而獲得更大的靈活性和可測試性。

想要把ServiceBean交給Spring來管理,我們需要一個XML配置文件。新建一個beans.xml,放到src目錄下,確保在classpath中能找到此配置文件,輸入以下內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" />
</beans>

以上XML聲明了一個id為service的Bean,默認地,Spring為每個聲明的Bean僅創(chuàng)建一個實例,并通過id來引用這個Bean。下面,我們修改main方法,讓Spring來管理業(yè)務Bean:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class Main {
    public static void main(String[] args) throws Exception {
        // init factory:
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
        // use service bean:
        ServiceBean service = (ServiceBean)factory.getBean("service");
        service.addUser("bill", "hello");
        service.addUser("tom", "goodbye");
        service.addUser("tracy", "morning");
        System.out.println("tom's password is /"" + service.getPassword("tom") + "/"");
        if(service.findUser("tom")) {
            service.deleteUser("tom");
        }
        // close factory:
        factory.destroySingletons();
    }
}


執(zhí)行結果:
 Spring入門(圖三)

由于我們要通過main方法啟動Spring環(huán)境,因此,首先需要初始化一個BeanFactory。紅色部分是初始化Spring的BeanFactory的典型代碼,只需要保證beans.xml文件位于classpath中。

然后,在BeanFactory中通過id查找,即可獲得相應的Bean的實例,并將其適當轉型為合適的接口。

接著,實現(xiàn)一系列業(yè)務操作,在應用程序結束前,讓Spring銷毀所有的Bean實例。

對比上一個版本的Main,可以看出,最大的變化是不需要自己管理Bean的生命周期。另一個好處是在不更改實現(xiàn)類的前提下,動態(tài)地為應用程序增加功能。

4.編寫Advisor以增強ServiceBean

所謂AOP即是將分散在各個方法處的公共代碼提取到一處,并通過類似攔截器的機制實現(xiàn)代碼的動態(tài)織入。可以簡單地想象成,在某個方法的調用前、返回前、調用后和拋出異常時,動態(tài)插入自己的代碼。在弄清楚Pointcut、Advice之類的術語前,不如編寫一個最簡單的AOP應用來體驗一下。

考慮一下通常的Web應用程序都會有日志記錄,我們來編寫一個LogAdvisor,對每個業(yè)務方法調用前都作一個記錄:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class LogAdvisor implements MethodBeforeAdvice {
    public void before(Method m, Object[] args, Object target) throws Throwable {
        System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");
    }
}

然后,修改beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
        <property name="target"><ref local="serviceTarget"/></property>
        <property name="interceptorNames">
            <list>
                <value>logAdvisor</value>
            </list>
        </property>
    </bean>
</beans>

注意觀察修改后的配置文件,我們使用了一個ProxyFactoryBean作為service來與客戶端打交道,而真正的業(yè)務Bean即MyServiceBean被聲明為serviceTarget并作為參數(shù)對象傳遞給ProxyFactoryBean,proxyInterfaces指定了返回的接口類型。對于客戶端而言,將感覺不出任何變化,但卻動態(tài)加入了LogAdvisor,關系如下:
 Spring入門(圖四)


運行結果如下,可以很容易看到調用了哪些方法:
 Spring入門(圖五)

要截獲指定的某些方法也是可以的。下面的例子將修改getPassword()方法的返回值:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class PasswordAdvisor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object ret = invocation.proceed();
        if(ret==null)
            return null;
        String password = (String)ret;
        StringBuffer encrypt = new StringBuffer(password.length());
        for(int i=0; i<password.length(); i++)
            encrypt.append('*');
        return encrypt.toString();
    }
}

這個PasswordAdvisor將截獲ServiceBean的getPassword()方法的返回值,并將其改為"***"。繼續(xù)修改beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
    <bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" />
    <bean id="passwordAdvisor" class="org.springframework.aop.support.RegeXPMethodPointcutAdvisor">
        <property name="advice">
            <ref local="passwordAdvisorTarget"/>
        </property>
        <property name="patterns">
            <list>
                <value>.*getPassword</value>
            </list>
        </property>
    </bean>
    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
        <property name="target"><ref local="serviceTarget"/></property>
        <property name="interceptorNames">
            <list>
                <value>logAdvisor</value>
                <value>passwordAdvisor</value>
            </list>
        </property>
    </bean>
</beans>


利用Spring提供的一個RegexMethodPointcutAdvisor可以非常容易地指定要截獲的方法。運行結果如下,可以看到返回結果變?yōu)?******":
 Spring入門(圖六)

還需要繼續(xù)增強ServiceBean?我們編寫一個ExceptionAdvisor,在業(yè)務方法拋出異常時能做一些處理:

/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit: http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
import org.springframework.aop.ThrowsAdvice;
public class ExceptionAdvisor implements ThrowsAdvice {
    public void afterThrowing(RuntimeException re) throws Throwable {
        System.out.println("[Exception] " + re.getMessage());
    }
}

將此Advice添加到beans.xml中,然后在業(yè)務Bean中刪除一個不存在的用戶,故意拋出異常:

service.deleteUser("not-exist");

再次運行,注意到ExceptionAdvisor記錄下了異常:
 Spring入門(圖七)

5.總結

利用Spring非常強大的IoC容器和AOP功能,我們能實現(xiàn)非常靈活的應用,讓Spring容器管理業(yè)務對象的生命周期,利用AOP增強功能,卻不影響業(yè)務接口,從而避免更改客戶端代碼。

為了實現(xiàn)這一目標,必須始終牢記:面向接口編程。而Spring默認的AOP代理也是通過Java的代理接口實現(xiàn)的。雖然Spring也可以用CGLIB實現(xiàn)對普通類的代理,但是,業(yè)務對象只要沒有接口,就會變得難以擴展、維護和測試。

歡迎來信與作者交流:asklxf@163.com

可以從此處下載完整的Eclipse工程:

springbasic.rar

(出處:http://m.survivalescaperooms.com)



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 通州区| 抚松县| 讷河市| 岳池县| 吐鲁番市| 青河县| 邻水| 防城港市| 栖霞市| 彭州市| 临泽县| 荥阳市| 年辖:市辖区| 舟山市| 青海省| 钦州市| 余干县| 西峡县| 大安市| 麦盖提县| 临邑县| 乾安县| 横峰县| 大埔县| 连江县| 当雄县| 张家口市| 石门县| 广河县| 南开区| 连城县| 浦城县| 博罗县| 杭锦旗| 静安区| 南和县| 黄冈市| 乌鲁木齐市| 和政县| 丹棱县| 离岛区|