说明:Spring IoC其实就是在Service的实现中定义了一些以来的策略类,这些策略类不是通过 初始化、Setter、工厂方法来确定的。而是通过一个叫做上下文的(ApplicationContext)组建来加载进来的。这里介绍两种Context组建的构件过程

前提条件:在Gradle工程的build.gradle文件中引入对Spring framework 的支持

repositories {
mavenCentral()
} dependencies {
compile group: 'org.springframework',name: 'spring-context', version: '4.1.5.RELEASE'
compile group: 'org.springframework',name: 'spring-core', version: '4.1.5.RELEASE'
testCompile group: 'junit', name: 'junit', version: '4.11'
}

第一种方式:通过ClassPathXmlApplicationContext加载xml配置文件

这里使用greenmail做测试邮件的例子来介绍:

1. 依赖管理

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.ygshen.mvnbook.account</groupId>
<artifactId>account-service</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.3.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency> <!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.icegreen/greenmail -->
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.5.2</version>
<scope>test</scope>
</dependency> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

2. 接口定义

public interface emailService {
public void sendMail(String to, String subject,String htmlText) throws MessagingException;
}

3. 接口实现

public class emailServiceImp implements emailService{
//这里有两个IOC的变量,后面将通过bean+property的方式进行依赖管理
private JavaMailSender javaMailSender;
private String systemAccount; // Get和Set时必须的
public JavaMailSender getJavaMailSender() {
return javaMailSender;
} public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
} public String getSystemAccount() {
return systemAccount;
} public void setSystemAccount(String systemAccount) {
this.systemAccount = systemAccount;
} //发送邮件主题函数,javamailsender是 spring的邮件类。这个mail sender就是发送邮件的smtp服务器。
// 如Gmail等,这里将在测试用例中使用greenemail代替他门
public void sendMail(String to, String subject, String htmlText) throws MessagingException {
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom(systemAccount);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(htmlText); javaMailSender.send(message);
}
}

4. Bean文件定义:

<?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">

<!--定义自动获取property配置-->
<bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:service.properties"></property>
</bean>
<!--定义java mail sender bean 对象,这个bean后边将作为依赖注入到service中-->
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="protocol" value="${email.protocol}"></property>
<property name="port" value="${email.port}"></property>
<property name="host" value="${email.host}"></property>
<property name="username" value="${email.username}"></property>
<property name="password" value="${email.password}"></property>
<property name="javaMailProperties">
<props>
<prop key="mail.${email.protocol}.auth">${email.auth}</prop>
</props>
</property> </bean>
<!--真正负责发送邮件的类定义bean-->
<bean id="accountService" class="com.ygshen.mvnbook.account.email.emailServiceImp">
<property name="javaMailSender" ref="javaMailSender"></property>
<property name="systemAccount" value="${email.systemAccount}"></property>
</bean>
</beans>

5. Property 文件

email.protocol=smtps
email.host=smtp.gmail.com
email.port=465
email.username=shenyuangong@gmail.com
email.password=111111
email.auth=true
email.systemAccount=ygshen@163.com

初始化javamailsender的配置文件。 main/Resources目录下。注意这个配置文件将在test/resource中 重新定义目的是模拟测试

6. 测试代码:

package com.ygshen.mvnbook.account;

import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;
import com.ygshen.mvnbook.account.email.emailService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.mail.Message;
import javax.mail.MessagingException; /**
* Created by ygshen on 16/10/31.
*/
//这里需要注意junit的测试文件必须以Test结尾 否则 mvn clean test 的时候将没有办法获取到测试用例
public class emailServiceTest {
//这里初始化一个本地的greenmail作为测试邮箱服务器
private GreenMail mail;
@Before
public void startMailBox(){
mail = new GreenMail(new ServerSetup(12000,null,"smtp"));
mail.setUser("shenyuangong@gmail.com", "123456");
mail.start();
}
@Test
public void sendMail() throws MessagingException {
ApplicationContext context = new ClassPathXmlApplicationContext("account-service.xml");
// 这里将初始化发送邮件的service,而service所依赖的javamailsender初始化所配置的邮箱服务器和start中 定义的port、protocol也是一样的。 在测试test/resources中定义。这里greenmail起到模拟gmail服务器的能力
emailService service = (emailService)context.getBean("accountService");
service.sendMail("test2@163.com","Test Subject","<h1>test</h1>");
mail.waitForIncomingEmail(2000,1);
Message[] msgs = mail.getReceivedMessages();
Assert.assertEquals(1,msgs.length);
}
@After
public void closeMail(){
mail.stop();
} }

7. 测试用的Properties文件

email.protocol=smtp
email.host=localhost
email.port=12000
# 注意这里的邮箱登陆的帐号要和Greenmail中 setUser使用的相同才行。
email.username=shenyuangong@gmail.com
email.password=123456
email.auth=true
email.systemAccount=ygshen@163.com

第二种方式:AnnotationConfigApplicationContext类加载JavaClass File的配置文件

配置文件JavaClass如下:

@Configuration:表示这是一个配置文件

@Bean: 表示这是一个Bean(名字为方法名),将来他要用来与Service中的@Autowired属性配对,注意配对的时候是根据返回类型来对应的,也就是说所有的Service中但凡有@Autowired的属性,他们都是从这个配置文件中拿到的。

@Configuration
public class ApplicationContextConfiguration {
@Bean
public AccountRepoisitory accountRepoisitory() {
return new AccountRepositoryImp();
} @Bean
public TransactionService transactionService() {
return new TransactionServiceImp();
} @Bean
public TransferService transferService() {
return new TransferServiceImp();
}
}

再来看一下使用@AutoWired的Service类。这个AutoWired将与上面配置文件中的@Bean结成一对儿

public class TransactionServiceImp implements TransactionService {

    @Autowired
public AccountRepoisitory accountRepoisitory;
@Override
public void NewTransaction(String accountId1, String accountId2, double money) {
Account account1=accountRepoisitory.GetAccountByAccountId(accountId1);
Account account2=accountRepoisitory.GetAccountByAccountId(accountId2);
Transaction transaction=new Transaction(){ };
transaction.fromAccount=account1;
transaction.toAccount=account2;
transaction.moneyTransfered=money;
transaction.transactionDate= Calendar.getInstance().getTime(); BankFactory.Transactions.add(transaction);
}
}

最后来看Main函数是如何将配置文件与Service文件结合在一起的。 很简单

  ApplicationContext context=
new AnnotationConfigApplicationContext(
com.ctrip.configuration.ApplicationContextConfiguration.class
); // 接下来我们就可以使用任何Service中定义的方法了
AccountRepoisitory accountRepoisitory=context.getBean("accountRepoisitory",
AccountRepositoryImp.class); TransactionService transactionService=context.getBean("transactionService",
TransactionServiceImp.class); TransferService transferService=context.getBean("transferService",
TransferServiceImp.class
);
transferService.Transfer("1","2",234);
 

Spring中IoC - 两种ApplicationContext加载Bean的配置的更多相关文章

  1. 两种动态加载JavaScript文件的方法

    两种动态加载JavaScript文件的方法 第一种便是利用ajax方式,第二种是,动静创建一个script标签,配置其src属性,经过把script标签拔出到页面head来加载js,感乐趣的网友可以看 ...

  2. Spring中ApplicationContext加载机制和配置初始化

    Spring中ApplicationContext加载机制.        加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet.        ...

  3. 死磕Spring之IoC篇 - BeanDefinition 的加载阶段(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  4. Spring中使用两种Aware接口自定义获取bean

    在使用spring编程时,常常会遇到想根据bean的名称来获取相应的bean对象,这时候,就可以通过实现BeanFactoryAware来满足需求,代码很简单: @Servicepublic clas ...

  5. iOS两种方式加载图片的区别

    加载图片的方式: imageNamed: imageWithContentsOfFile: 加载Assets.xcassets这里面的图片: 1> 打包后变成Assets.car 2> 拿 ...

  6. 【Spring源码分析系列】加载Bean

    /** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * ...

  7. Spring在Web项目中的三种启动加载的配置

    在最近的项目中,使用到了spring相关的很多东西,有点把spring的配置给搞混了,从网上查到的资料以及整理了一下. 在Web项目中,启动spring容器的方式有三种,ContextLoaderLi ...

  8. MyEclipse10 中的两种FreeMarker插件的安装与配置

    第一个插件是:                                       freemarker-ide MyEclipce10.0中安装FreeMarker插件,这绝对是最简单的方法 ...

  9. 深入理解 spring 容器,源码分析加载过程

    Spring框架提供了构建Web应用程序的全功能MVC模块,叫Spring MVC,通过Spring Core+Spring MVC即可搭建一套稳定的Java Web项目.本文通过Spring MVC ...

随机推荐

  1. du与df为什么有时候会有差异

    以下仅为本人理解,非官方! du命令:统计父目录的目录项,若目录项存在,则进行查找 df命令:统计inode节点,根据inode节点存储的块大小进行统计 差异原因: 当一个文件被进程调用后,复制文件到 ...

  2. OS-MAC: An Efficient MAC Protocol for Spectrum-Agile Wireless Networks

    IEEE TRANSACTIONS ON MOBILE COMPUTING, VOL. 7, NO. 8, AUGUST 2008 正如之前所说的,这是一个out-of-band local cove ...

  3. TEA encryption with 128bit key

    If anyone needs some basic encryption in software, here's one solution. This TEA implementation fits ...

  4. http cookie

    一.cookie的大小 cookie只能存储最大4kb的数据.cookie的名/值中的值不允许包含分号.逗号和空白符.因此可以采用encodeURIComponent()编码,读取的时候先采用deco ...

  5. 使用 asp.net Web API 2的坑

    使用工具: Googl  浏览器+PostMan 插件 写了个  控制器 添加了个Action,结果呢?GET 方式请求没问题. POST一直,在服务器端获取不了参数...找了官方的文档 .各种雨里雾 ...

  6. 【Xamarin挖墙脚系列:代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧(转)】

    正愁如何选择构建项目中的视图呢,现在官方推荐画板 Storybord...但是好像 xib貌似更胜一筹.以前的老棒子总喜欢装吊,用代码写....用代码堆一个HTML页面不知道你们尝试过没有.等页面做出 ...

  7. 【转】 linux内核移植和驱动添加(三)

    原文网址:http://blog.chinaunix.net/uid-29589379-id-4708909.html 原文地址:linux内核移植和驱动添加(三) 作者:genehang 四,LED ...

  8. codecomb 2086【滑板鞋】

    题目背景 我的滑板鞋时尚时尚最时尚 回家的路上我情不自禁 摩擦 摩擦 在这光滑的地上摩擦 月光下我看到自己的身影有时很远有时很近 感到一种力量驱使我的脚步 有了滑板鞋天黑都不怕 题目描述 你在魅力之都 ...

  9. C语言随笔_return答疑

    1. 例子,看实例2-2.这道题有同学会问,那个return有什么用?这么讲吧,return是个英文单词,中文意思是“返回”,用在程序里也是返回的意思,返回啥呢?返回一个值.在func函数中,retu ...

  10. 【转】android 电容屏(二):驱动调试之基本概念篇

    关键词:android  电容屏 tp 工作队列 中断 多点触摸协议平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310(samsung ...