SpringIOC-注入的方式
2019-01-03 本文已影响17人
do_young
前言
为了方便对各个注入方式写例子,自己创建了一个工程。
创建一个spring工程
首先创建一个maven工程 ,引入spring-context包,我这里使用的是4.3.12.RELAESE版本。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
</dependencies>
根据依赖关系,会引入以下的spring包。
spring-context.png
方法一:基于xml
创建一个pojo对象User
package com.going.spring.bean;
public class User {
private String name;
private Integer age;
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User(String name, Integer age, String nikeName) {
super();
this.name = name;
this.age = age;
this.nickName = nikeName;
}
public User() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
}
}
创建一个xml配置文件beans-user.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="user" class="com.going.spring.bean.User" >
<property name="age" value="1"></property>
<property name="name" value="doyoung"></property>
<property name="nickName" value="doyoungdy"></property>
</bean>
</beans>
测试类
package com.going.spring.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserXmlIocTest extends User {
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans-user.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user);
}
}
方法二:基于注解
对POJO对象添加注解
package com.going.spring.bean.anno;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class UserAnno {
@Value("doyoung")
private String name;
@Value("21")
private Integer age;
@Value("doyoungdy")
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public UserAnno(String name, Integer age, String nikeName) {
super();
this.name = name;
this.age = age;
this.nickName = nikeName;
}
public UserAnno() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
}
}
创建一个xml配置文件beans-useranno.xml,指定加载配置注解类的路径
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.going.spring.bean.anno" ></context:component-scan>
</beans>
- 注:当然也可以使用配置类使用@ComponentScans注解来做相同的配置。
测试类
package com.going.spring.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.going.spring.bean.anno.UserAnno;
public class UserAnnoIocTest extends User {
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans-useranno.xml");
UserAnno user = (UserAnno) applicationContext.getBean(UserAnno.class);
System.out.println(user);
}
}
方法三:基于配置类
创建一个配置类
说明在当前ioc容器中,当需要一个User对象的时候,就通过配置类中的user方法,创建一个User对象。
package com.going.spring.bean.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.going.spring.bean.User;
@Configuration
public class UserAnnoConfig {
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("user")
public User user(){
return new User("doyoung", 23, "doyoungdy");
}
}
测试类
通过AnnotationConfigApplicationContext类创建一个Spring的容器,在参数中配置对应的配置类。
package com.going.spring.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.going.spring.bean.config.UserAnnoConfig;
public class UserConfiglIocTest extends User {
@Test
public void test() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserAnnoConfig.class);
User user = (User) applicationContext.getBean("user");
System.out.println(user);
}
}
(注:其实配置类也可以归类于基于注解的方法。
方法四:@Import标签
可以直接使用Import标签,在里面配置需要注入的类,如:
@Configuration
@Import({User.class, UserAnno.class})
public class UserImportConfig {
}
方法五:@Import标签+ImportSelector接口
实现一个ImportSelector接口:
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import com.going.spring.bean.User;
import com.going.spring.bean.anno.UserAnno;
public class UserImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{User.class.getName(),UserAnno.class.getName()};
}
}
将ImportSelector接口的实现类配置在@Import注解中:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({UserImportSelector.class})
public class UserImportConfig2 {
}
方法六:@Import标签+ImportBeanDefinitionRegistrar接口
实现一个ImportBeanDefinitionRegistrar接口:
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import com.going.spring.bean.User;
import com.going.spring.bean.anno.UserAnno;
public class UserBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
registry.registerBeanDefinition("user", beanDefinition);
beanDefinition = new RootBeanDefinition(UserAnno.class);
registry.registerBeanDefinition("userAnno", beanDefinition);
}
}
将ImportBeanDefinitionRegistrar 接口的实现类配置在@Import注解中:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({UserBeanDefinitionRegistrar.class})
public class UserImportConfig3 {
}
方法七:FactoryBean
实现一个FactoryBean接口:
import org.springframework.beans.factory.FactoryBean;
import com.going.spring.bean.User;
public class UserFactoryBean implements FactoryBean<User> {
public User getObject() throws Exception {
return new User();
}
public Class<?> getObjectType() {
return User.class;
}
public boolean isSingleton() {
return false;
}
}
通过配置类将UserFactoryBean注入到容器中:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserImportConfig4 {
@Bean
public UserFactoryBean colorFactoryBean(){
return new UserFactoryBean();
}
}