zoukankan      html  css  js  c++  java
  • Spring中IoC

    说明: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);
     
  • 相关阅读:
    HDU 5791 Two (DP)
    POJ 1088 滑雪 (DPor记忆化搜索)
    LightOJ 1011
    POJ 1787 Charlie's Change (多重背包 带结果组成)
    HDU 5550 Game Rooms (ccpc2015 K)(dp)
    HDU 5542 The Battle of Chibi (ccpc 南阳 C)(DP 树状数组 离散化)
    HDU 5543 Pick The Sticks (01背包)
    HDU 5546 Ancient Go (ccpc2015南阳G)
    NB-IoT的DRX、eDRX、PSM三个模式 (转载,描述的简单易懂)
    MQTT 嵌入式端通讯协议解析(转)
  • 原文地址:https://www.cnblogs.com/ygshen/p/4346943.html
Copyright © 2011-2022 走看看