SpringCore 官网知识整理

Spring Core

2021-12-04 23:30:23 星期六

XML-Based Configuration

XML-based configuration metadata configures these beans as <bean/> elements inside a top-level <beans/> element.


<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="..."> ① ②
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>

① The id attribute is a string that identifies the individual bean definition.

② The class attribute defines the type of the bean and uses the fully qualified classname

Composing XML-based Configuration Metadata

  <!--using the relative loaction path to the definition file doing the importing . So services.xml must be in the same directory or classpath location as the file doing the importing. -->
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>

messageSource.xml and themeSource.xml must be in a resources location below the location of the importing file.


Contructor-based Dependency Injection

Using explict <constructor-arg/> element to specify the construtor argument.

<beans>

<!-- the ThingTwo and ThingThree classes are not related by inheritance, no potential ambiguity exists. -->
<bean id="beanOne" class="x.y.ThingOne">
<constructor-arg ref="beanTwo"/>
<constructor-arg ref="beanThree"/>
</bean>

<bean id="beanTwo" class="x.y.ThingTwo"/>
<bean id="beanThree" class="x.y.ThingThree"/>

</beans>

Constructor argument index

use index attribute to specify explicitly the index of constructor arguments.

NOTE: The index is 0-based.

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
</bean>

Constructor argument name

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg name="years" value="7500000"/>
<constructor-arg name="ultimateAnswer" value="42"/>
</bean>

your code must be compiled with the debug flag enabled so that Spring can look up the parameter name from the constructor. Or you can use the @ConstructorProperties JDK annotation to explicitly name your constructor arguments.

package examples;

public class ExampleBean {
      // Fields omitted
      @ConstructorProperties({"years", "ultimateAnswer"})
      public ExampleBean(int years, String ultimateAnswer) {
                this.years = years;
                this.ultimateAnswer = ultimateAnswer;
      }
}

Setter-based Dependency Injection

<bean id="exampleBean" class="examples.ExampleBean">
<!-- setter injection using the nested ref element -->
<property name="beanOne"> 
<ref bean="anotherExampleBean"/>
</property>
<!-- setter injection using the neater ref attribute -->
<property name="beanTwo" ref="yetAnotherBean"/>
<property name="integerProperty" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

Instantiation with a Stactic Factory Method

Use the class attribute to specify the class that contains the static factory method and an attribute named factory-method to specify the name of the factory method itself.

<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
public class ClientService {
        private static ClientService clientService = new lientService();

        private ClientService() {}

        public static ClientService createInstance() {
            return clientService;
        }
}

Instantiation by Using an Instance Factory Mehthod.

Similar to the priew a static factory method.

<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/>

<bean id="accountService"  factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>

public class DefaultServiceLocator {
        private static ClientService clientService = new ClientServiceImpl();
        private static AccountService accountService = new AccountServiceImpl();

        public ClientService createClientServiceInstance() {
            return clientService;
        }
        public AccountService createAccountServiceInstance() {
            return accountService;
        }
}

Java configuration typically uses @Bean-annotated
methods within a @Configuration class.

XML Shortcut With the p-namespace

The p-namespace lets you use the bean element's attribute to describe your property values collaborating beans, or both.

The p-namespace is not defined in an XSD file and exists only in the core of Spring.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="classic" class="com.example.ExampleBean">
<property name="email" value="someone@somewhere.com"/>
</bean>
<bean name="p-namespace" class="com.example.ExampleBean"
p:email="someone@somewhere.com"/>

<!-- more example -->
<bean name="john-classic" class="com.example.Person">
<property name="name" value="John Doe"/>
<property name="spouse" ref="jane"/>
</bean>
<bean name="john-modern" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane"/>
<bean name="jane" class="com.example.Person">
<property name="name" value="Jane Doe"/>
</bean>

</beans>

XML Shortcut With the c-namespace

<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
      
      <bean id="beanTwo" class="x.y.ThingTwo"/>
      <bean id="beanThree" class="x.y.ThingThree"/>
<!-- traditional declaration with optional argument names -->
      <bean id="beanOne" class="x.y.ThingOne">
            <constructor-arg name="thingTwo" ref="beanTwo"/>
            <constructor-arg name="thingThree" ref="beanThree"/>
            <constructor-arg name="email" value="something@somewhere.com"/>
      </bean>
<!-- c-namespace declaration with argument names -->
      <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo" c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

<!-- c-namespace index declaration -->
      <bean id="beanOne" class="x.y.ThingOne" c:_0-ref="beanTwo" c:_1-ref="beanThree" c:_2="something@somewhere.com"/>

</beans>

Note: the index notation requires the presence of the leading _.

note :The <null/> element handles null values.


Lazy-initialized Beans

lazy-init

Scoped bean as Depedencies

When injecting a shorter-lived scoped bean into a longer-lived scoped bean (for example,injecting an HTTP Session-scoped collaborating bean as a dependency into singleton bean). using <aop:scoped-proxy/&gt element.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd 
                    http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
<!-- instructs the container to proxy the surrounding bean -->
          <aop:scoped-proxy/> 
</bean>
<!-- a singleton-scoped bean injected with a proxy to the above bean -->
<bean id="userService" class="com.something.SimpleUserService">
<!-- a reference to the proxied userPreferences bean -->
      <property name="userPreferences" ref="userPreferences"/>
</bean>
</beans>

Annoation-based Container Configuration

Annotation injection is performed before XML injection. Thus, the XML configuration overrides the annotations for properties wired through both approaches.

@Reuqired :This annotation indicates that the affected bean property must be populated at configuration time.

@AutoWired :

@Primary : collaborating with @AutoWired annotation.indicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency.If exactly one primary bean exists among the candidates, it becomes the autowired value.

@Qualifier :type-driven injection. See official doc. main for narrowing down to the specify beans. The default value is the bean name (id defined in xml file).

@Resource takes a name attribute. By default, Spring interprets that value as the bean name to be injected. (unique )

@Value is typically used to inject externalized properties:

@Component
public class MovieRecommender {
      private final String catalog;
      public MovieRecommender(@Value("${catalog.name}") String catalog) {
            this.catalog = catalog;
      }
}

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }
posted @ 2022-01-22 19:05  编程打工人  阅读(84)  评论(0)    收藏  举报