Spring參考手冊 7 綜合

翻譯自Spring官方文檔 4.1.2版本

相關(guān)文章:

一伸刃、在Spring中使用遠(yuǎn)程調(diào)用

Spring集成了多個可以遠(yuǎn)程調(diào)用的技術(shù)枷邪。遠(yuǎn)程調(diào)用支持開發(fā)遠(yuǎn)程服務(wù)哄辣,用普通的POJO即可實(shí)現(xiàn)。目前Spring支持以下幾個遠(yuǎn)程調(diào)用技術(shù):

  • Remote Method Invocation (RMI)
  • Spring HTTP invoker
  • Hessian
  • Burlap
  • Java Message Service(JMS)贩猎,在底層使用JMS作為協(xié)議
  • Advanced Message Queuing Protocol(AMQP)收夸,在底層使用AMQP作為協(xié)議

Spring自動發(fā)現(xiàn)功能不適用于遠(yuǎn)程接口蜗顽,主要是為了避免對遠(yuǎn)程調(diào)用者開啟太多的入口布卡。

當(dāng)討論Spring的遠(yuǎn)程調(diào)用能力時我們使用以下實(shí)體類和相應(yīng)的services:

public class Account implements Serializable{

    private String name;

    public String getName(){
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
public interface AccountService {

    public void insertAccount(Account account);

    public List<Account> getAccounts(String name);

}
public class AccountServiceImpl implements AccountService {

    public void insertAccount(Account acc) {
        // do something...
    }

    public List<Account> getAccounts(String name) {
        // do something...
    }

}

使用RMI的就不翻譯了,性能不太好雇盖。只翻譯一個Hessian忿等。Burlap與Hessian配置方式一樣,只需要把Hessian這個詞換成Burlap就行了崔挖。AMQP看這里贸街。關(guān)于它Spring另外有個項(xiàng)目。

1.1 使用Hessian通過HTTP遠(yuǎn)程調(diào)用services

Hessian提供了一個二進(jìn)制基于HTTP的遠(yuǎn)程調(diào)用協(xié)議狸相。更多信息請查看薛匪。

Hessian通過HTTP溝通,我們可以自定義一個servlet脓鹃。你可以輕松的寫出如下這樣的一個servlet來曝露你的服務(wù)逸尖。

<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>remoting</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

然后在WEB-INF文件夾創(chuàng)建一個remoting-servlet.xml配置文件

1.1.1 使用HessianServiceExporter曝露你的beans

我們將會在remoting-servlet.xml配置文件中創(chuàng)建一個HessianServiceExporter來曝露你的服務(wù):

<bean id="accountService" class="example.AccountServiceImpl"></bean>

<bean name="/AccountService" class="org.springframework.remoting.caucho.HessianServiceExporter">
    <property name="service" ref="accountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

現(xiàn)在我們?nèi)?zhǔn)備在客戶端連接服務(wù)。沒有顯式的處理器映射被指定瘸右,那么BeanNameUrlHandlerMapping將會被使用娇跟,因此,這個服務(wù)將會曝露在DispatcherServlet的映射下并且以bean名稱(也就是/AccountService)命名的URL:http://HOST:8080/remoting/AccountService

1.1.2 在客戶端連接服務(wù)

使用HessianProxyFactoryBean我們可以在客戶端鏈接服務(wù)太颤。SimpleObject使用AccountService來管理賬戶:

<bean class="example.SimpleObject">
    <property name="accountService" ref="accountService"/>
</bean>

<bean id="accountService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
    <property name="serviceUrl" value="http://remotehost:8080/remoting/AccountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

1.2 對使用Hessian或者Burlap曝露的服務(wù)應(yīng)用HTTP基本身份驗(yàn)證

Hessian 和 Burlap的協(xié)議都是基于HTTP的苞俘,你可以很輕松的使用HTTP基本身份驗(yàn)證,例如:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors" ref="authorizationInterceptor"/>
</bean>

<bean id="authorizationInterceptor"
        class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">
    <property name="authorizedRoles" value="administrator,operator"/>
</bean>

在這個應(yīng)用程序上下文中這個攔截器只允許administrators 和 operators這兩個角色調(diào)用bean方法龄章。

具體文檔也沒說吃谣,有興趣可以自行搜索,Apache Shiro也可以使用做裙。

二岗憋、在Spring中使用郵件

首先添加第三方依賴:

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.5.6</version>
</dependency>

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

org.springframework.mail包是Spring Framework email支持的根級別包。發(fā)送郵件的核心接口是MailSender菇用;SimpleMailMessage類封裝了封裝一個簡單郵件的屬性例如發(fā)件人澜驮、收件人陷揪。 這個包還提供了一個統(tǒng)一的郵件異常MailException惋鸥。

org.springframework.mail.javamail.JavaMailSender接口添加了JavaMail的特性,例如MIME信息支持悍缠。JavaMailSender還為JavaMail MIME消息的準(zhǔn)備活動提供了一個回調(diào)接口org.springframework.mail.javamail.MimeMessagePreparator卦绣。

2.1 用法

我們假設(shè)這里有一個業(yè)務(wù)接口叫做OrderManager

public interface OrderManager {

    void placeOrder(Order order);

}

2.1.1 MailSender 和 SimpleMailMessage的基本用法

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class SimpleOrderManager implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage templateMessage;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setTemplateMessage(SimpleMailMessage templateMessage) {
        this.templateMessage = templateMessage;
    }

    public void placeOrder(Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        // 創(chuàng)建一個線程安全的template message副本并且自定義它
        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
        msg.setTo(order.getCustomer().getEmailAddress());
        msg.setText(
            "Dear " + order.getCustomer().getFirstName()
                + order.getCustomer().getLastName()
                + ", thank you for placing order. Your order number is "
                + order.getOrderNumber());
        try{
            this.mailSender.send(msg);
        }
        catch (MailException ex) {
            // 簡單的輸出它,然后繼續(xù)
            System.err.println(ex.getMessage());
        }
    }

}

下面是一些bean定義:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="mail.mycompany.com"/>
</bean>

<!-- 這是一個template message飞蚓,使用默認(rèn)狀態(tài)預(yù)加載它 -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
    <!-- 發(fā)件人 -->
    <property name="from" value="customerservice@mycompany.com"/>

    <!-- 郵件主題 -->
    <property name="subject" value="Your order"/>
</bean>

<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
    <property name="mailSender" ref="mailSender"/>
    <property name="templateMessage" ref="templateMessage"/>
</bean>

2.1.2 使用JavaMailSender 和 MimeMessagePreparator

這是另一個OrderManager實(shí)現(xiàn)滤港,使用的了MimeMessagePreparator回調(diào)接口。請注意mailSender參數(shù)是JavaMailSender類型,這樣我們便可使用JavaMail的MimeMessage類:

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class SimpleOrderManager implements OrderManager {

    private JavaMailSender mailSender;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void placeOrder(final Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {

                mimeMessage.setRecipient(Message.RecipientType.TO,
                        new InternetAddress(order.getCustomer().getEmailAddress()));
                mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
                mimeMessage.setText(
                        "Dear " + order.getCustomer().getFirstName() + " "
                            + order.getCustomer().getLastName()
                            + ", thank you for placing order. Your order number is "
                            + order.getOrderNumber());
            }
        };

        try {
            this.mailSender.send(preparator);
        }
        catch (MailException ex) {
            // 簡單的輸出它溅漾,然后繼續(xù)
            System.err.println(ex.getMessage());
        }
    }

}

更多信息請參考JavaMail的javadoc山叮。

2.1.3 使用JavaMail MimeMessageHelper

// 在現(xiàn)實(shí)中這里是通過依賴注入獲得的
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("test@host.com");
helper.setText("Thank you for ordering!");

sender.send(message);

發(fā)送附件與內(nèi)聯(lián)資源

附件好理解,內(nèi)聯(lián)資源舉個例子可以是圖片或者Excel顯式在你的郵件正文中而不是作為一個附件顯示添履。

附件

下面這個例子展示了如何使用MimeMessageHelper來發(fā)送一封郵件并且使用一張圖片作為附件:

// 在現(xiàn)實(shí)中這里是通過依賴注入獲得的
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// 使用true標(biāo)識指明你需要一個multipart信息
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test@host.com");

helper.setText("Check out this image!");

// 讓我們添加一個附件
FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addAttachment("CoolImage.jpg", file);

sender.send(message);

內(nèi)聯(lián)資源

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test@host.com");

// use the true flag to indicate the text included is HTML
helper.setText("<html><body><img src='cid:identifier1234'></body></html>", true);

// let's include the infamous windows Sample file (this time copied to c:/)
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);

sender.send(message);

一個基于Velocity的例子

要使用Velocity來創(chuàng)建你的郵件模版屁倔,你首先要將Velocity的類庫引入。

創(chuàng)建模版頁面:

# in the com/foo/package
<html>
    <body>
        <h3>Hi ${user.userName}, welcome to the Chipping Sodbury On-the-Hill message boards!</h3>

        <div>
            Your email address is <a href="mailto:${user.emailAddress}">${user.emailAddress}</a>.
        </div>
    </body>
</html>

配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="mail.csonth.gov.uk"/>
    </bean>

    <bean id="registrationService" class="com.foo.SimpleRegistrationService">
        <property name="mailSender" ref="mailSender"/>
        <property name="velocityEngine" ref="velocityEngine"/>
    </bean>

    <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
        <property name="velocityProperties">
            <value>
                resource.loader=class
                class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
            </value>
        </property>
    </bean>

</beans>
package com.foo;

import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;

public class SimpleRegistrationService implements RegistrationService {

    private JavaMailSender mailSender;
    private VelocityEngine velocityEngine;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    public void register(User user) {

        // Do the registration logic...

        sendConfirmationEmail(user);
    }

    private void sendConfirmationEmail(final User user) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
                message.setTo(user.getEmailAddress());
                message.setFrom("webmaster@csonth.gov.uk"); // could be parameterized...
                Map model = new HashMap();
                model.put("user", user);
                String text = VelocityEngineUtils.mergeTemplateIntoString(
                        velocityEngine, "com/dns/registration-confirmation.vm", model);
                message.setText(text, true);
            }
        };
        this.mailSender.send(preparator);
    }

}

未完暮胧,待續(xù)...

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锐借,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子往衷,更是在濱河造成了極大的恐慌钞翔,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件席舍,死亡現(xiàn)場離奇詭異布轿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俺亮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門驮捍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脚曾,你說我怎么就攤上這事东且。” “怎么了本讥?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵珊泳,是天一觀的道長。 經(jīng)常有香客問我拷沸,道長色查,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任撞芍,我火速辦了婚禮秧了,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘序无。我一直安慰自己验毡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布帝嗡。 她就那樣靜靜地躺著晶通,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哟玷。 梳的紋絲不亂的頭發(fā)上狮辽,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼喉脖。 笑死椰苟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的树叽。 我是一名探鬼主播尊剔,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼隘蝎,長吁一口氣:“原來是場噩夢啊……” “哼痒玩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旭绒,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤仇轻,失蹤者是張志新(化名)和其女友劉穎京痢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篷店,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祭椰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疲陕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片方淤。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蹄殃,靈堂內(nèi)的尸體忽然破棺而出携茂,到底是詐尸還是另有隱情,我是刑警寧澤诅岩,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布讳苦,位于F島的核電站,受9級特大地震影響吩谦,放射性物質(zhì)發(fā)生泄漏鸳谜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一式廷、第九天 我趴在偏房一處隱蔽的房頂上張望咐扭。 院中可真熱鬧,春花似錦滑废、人聲如沸蝗肪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽穗慕。三九已至饿敲,卻和暖如春妻导,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工倔韭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留术浪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓寿酌,卻偏偏與公主長得像胰苏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子醇疼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容