• 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);
     
  • 相关阅读:
    【HDOJ】1558 Segment set
    【HDOJ】2395 Alarm Clock
    【HDOJ】4278 Faulty Odomete
    【HDOJ】2571 命运
    【HDOJ】2150 Pipe
    【HDOJ】1277 全文检索
    【HDOJ】1134 Game of Connections
    【HDOJ】5131 Song Jiang's rank list
    【HDOJ】2772 Matchsticks
    【HDOJ】2577 How to Type
  • 原文地址:https://www.cnblogs.com/ygshen/p/4346943.html
Copyright © 2020-2023  润新知