zoukankan      html  css  js  c++  java
  • Spring Basics

    不知不觉在这个项目上做了快一年,但是却一直懒得没好好系统学习Spring framework,只是知道在哪里改一些设置。

    Spring里的IoC是由Dependency injection实现的:

    先说Dependency injection,比如Business logic需要一个功能saveCopy(),在真正的实现层有磁盘存储类DiskSaver,也有USB存储类UsbSaver。

    1, 不好的设计是:在Business logic层的saveCopy()里hardcode出底层实现的类: DiskSaver diskSaver = new DiskSaver(); diskSaver.save();。缺点是:一旦更换底层实现,上层也需要更改。

    2, 好的设计是: 上层类里面用setXXX(Interface downSaver)方法传入底层类,这样上层类里面就不会有底层的类名,只需要依赖于介面,而底层类也依赖于同一个介面:class DiskSaver implements downSaver { save()...}.

    所以通过Dendency injection,就可以实现控制反转,不是上层要求下层的细节,而是下层主动提供给上层它的需要。 

    一个用spring的例子:

    class example{

    private String helloWord;

    public void sethelloWord( String helloWord) { this.helloWord = helloWord;}

    public String gethelloWord() { return this.helloWord;}

    }

    在xml config file中,即可以用<property>tag来传入helloWord。例如:

    <bean id="myExample" class="xx.xx.xx.example">

    <property name="helloWord">

    <value>hello!</value>

    </property></bean>

    用set方法是Dependency injection的实现方法之一,spring还支持constructor。

    即public example(String helloWord) {

    this.helloWord = helloWord;}

    在xml里面用<constructor-arg index="0"> <value>hello!</value> </constructor-arg>

    在xml里面定义bean的name,class,property等并没有真正建立object,要需要在主程序里用BeanFactory或是ApplicationContext去getBean("myExample")才是真正建立的一个实现。

    Update on Sept 16 2014

    @Configuration
    @ComponentScan
    public class Application {

      @Bean
      MessageService helloWorldMessageService() {
        return new HelloWorldMessage();       //This class is just a simple implementation of MessageService interface
      }

      public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        MessageService service = context.getBean(MessageService.class);
        System.out.println(service.getMessage());
      }
    }

    The Spring Framework’s primary goal is to offer a dependency injection container that will facilitate the creation of instances and interaction between objects. The Spring Framework has several mechanisms to accomplish this: by name or by type. The injection can be either using Setters methods or constructors. 

    ApplicationContext的具体implementation class有:

    1, AnnotationConfigApplicationContext(CurrentClass.class); 这个需要将当前class用@Configuration, @ComponentScan和将Bean的方法用@Bean来注释。

    2, ClassPathXmlApplicationContext("currentApp-context.xml"); 这个需要新建一个context.xml,包含Bean definitions.

    3, Or before your test class, use @ContextConfiguration(locations="/GalaxyContext.xml"). Your test class should extend AbstractTestNGSpringContextTests class, to be able to use this annotation.

    A Java bean只是一种规范, conventions like method naming (set/get/is), a public no-arg construction, implements Serializable, so it can be reusable and it can interact with other beans and other classes. Later, in the Java community, the Java bean was transformed to the well-known POJO: Plain Old Java Object.

    相对的, A POJO (plain-old-Java-object) isn't rigorously defined. It's a Java object that doesn't have a requirement to implement a particular interface or derive from a particular base class, or etc.

    About create Bean in Spring xml config:

    By default, the bean will be created as a singleton instance; Or you can specify the scope as Prototype/Request/Session.

    <bean id="type" class="MyDocuments.Type" scope="prototype">

      <property name="name" value="WEB"/>
      <property name="desc" value="Web Link" />
      <property name="extension" value=".url" />
    </bean>

    If it is annotation/Java Configuration class, use @Scope("prototype"). 

    About create Bean in Annotation:

    Use annotation: @Component("id"), @Service, @Repository, @Controller, before class definition

    如果你的class有member variable,可以用@Autowired:

    @Autowired
    private DocumentDAO documentDAO;

    是将其它地方已经create好的bean赋给这个variable。

    不要忘记,在context.xml要加上<context:component-scan base-package="xxx"/>,to tell Spring container to start looking for annotated classes.

    Configuration:

    1, XML

    2, Java Bean Conguration: @Configuration before java ConfigurationClass. Use @Bean before method.

    Property as Collections in XML configuration:

    在定义<bean>的时候,你的property可能接受Collection类型,所以:

    <property name="documents">
             <list>
                 <ref bean="doc1"/>
                 <ref bean="doc2"/>
                 <ref bean="doc3"/>
                 <ref bean="doc4"/>
             </list>
    </property>

    或者

    <util:list id="docs">
              <ref bean="doc1"/>
              <ref bean="doc2"/>
              <ref bean="doc3"/>
              <ref bean="doc4"/>
    </util:list>
    <bean id="documentDAO" class="com.apress.isf.spring.data.DocumentRepository">
         <property name="documents" ref="docs"/>
    </bean>

    Load Resource file:这里Resource file指的是普通的文件,不是properties file。Resource class is from org.springframework.core.io package, 

    Add the menu.txt file under main/resources/META-INF/data/ folder, 
    Resource resource = context.getResource("classpath:META-INF/data/menu.txt");

    InputStream stream = resource.getInputStream();
    Scanner scanner = new Scanner(stream);
    while (scanner.hasNext()) {
          System.out.println(scanner.nextLine());
    }

    Load Properties file:

    <bean id="environmentProperties" class=" org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value=" classpath:META-INF/data/env_dev.properties"/>
    </bean>
    <bean id="login" class="com.apress.isf.spring.service.LoginService">
        <property name="username" value="${user.email}"/>
        <property name="password" value="${user.pass}"/>
    </bean>
    The Spring Framework does not allow 3rd party frameworks such as Apache Camel to seamless hook into the Spring property placeholder mechanism. However you can easily bridge Spring and Camel by declaring a Spring bean with the typeorg.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer, which is a Springorg.springframework.beans.factory.config.PropertyPlaceholderConfigurer type.

    for example, in B project:

    <bean p:locations="classpath*:env/${sut.env}-*.properties" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"
    p:systemPropertiesModeName="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>

    Spring properties:

    方法一:In Spring configuration file, import spring-util schema <util:properties id="propSource" location="classpath:/sample-properties/prop1.properties"/>

    使用时 @Value("#{propSource[message1]}")

    在.properties文件里有message1=xxx

    方法二:spring-context schema  使用时@Value("${message2}")

    <context:property-placeholder location="classpath:/.."/>

    方法三:spring-util schema

    <bean id = "propSource" class="org.spring.framework.beans.factory.config.PropertyPlaceholderConfigurer">

      <property name="location" value="classpath:/sample-pr..."/>

    </bean>

    使用时同上

    方法四:PropertyPlaceholderConfigurer 有子类BridgePropertyPlaceholderConfigurer, 因为Spring不允许第三方框架如camel使用它的property,所以要用bridge.

    <bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">

      <property name="location" value="classpath:.."/>

    </bean>

    使用时bean用${}, Camel routes用{{}}.

     
     


  • 相关阅读:
    优化-UITableView性能
    优化-预渲染加速iOS设备的图像显示
    UIWebView
    NSJSONSerialization
    UITableView UITableViewCell NSIndexPath
    NSDictionary NSMutableDictionary
    iOS Delegate NSNotificationCenter
    Php解决跨域名共享session方案整理专题
    memached共享session
    二级域名 session共享
  • 原文地址:https://www.cnblogs.com/chayu3/p/3074481.html
Copyright © 2011-2022 走看看