IoC的本质是由Spring的容器(应用程序上下文,即:ApplicationContext)来存储和管理在业务中需要用到的对象。
管理本身由容器负责,容器还负责将指定的对象注入的相应的位置;但将对象放入容器和指出想要取出对象的工作需要人工处理。
将对象放入容器的工作一般分为三种:通过xml文件设置或通过xml+注解配置、通过纯配置文件+注解配置。
分析三种方式:
(1)xml文件配置的方式已经过时了,目前处在衰退期。
(2)主流的配置方式是基于注解的配置,相对xml文件的配置方式来说,效率高、简单和好理解。
(3)纯配置文件配置的方式仅是一种对未来应用模拟,纯配置文件配置的方式更多用来代替web.xml,applicationContext.xml中的核心配置方式。
IoC的基本工作原理
1)Spring的工厂代替原来所有的工厂,只有spring的工厂会生成对象了,而该工厂可以生产一切对象。
2)Spring的工厂根据ApplicationContext.xml中的定义进行生产。
3)利用DI技术将Spring工厂生产的对象,注入到需要的类中去,注入的方法是利用set方法(也可以是构造器注入或接口注入)。
4)利用ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");语句将要生产的对象提供给工厂。
5)利用context.getBean("...")语句从工厂获得其生产的产品。
以下对注解形式的IoC进行更详细的使用说明:(注解配置)
首先建一个实体类User:
1 package com.zhaoming.annotation.entity; 2 import javax.annotation.Resource; 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5 6 @Component("user") //将当前类的对象,加载到应用程序上下文,并指定一个唯一的名字user 7 public class User { 8 @Value("1") 9 private int id; 10 @Value("喜洋洋") 11 private String name; 12 @Value("123456") 13 private String password; 14 @Resource 15 private UserDetail userDetail; 16 public int getId() { 17 return id; 18 } 19 public void setId(int id) { 20 this.id = id; 21 } 22 public String getName() { 23 return name; 24 } 25 public void setName(String name) { 26 this.name = name; 27 } 28 public String getPassword() { 29 return password; 30 } 31 public void setPassword(String password) { 32 this.password = password; 33 } 34 public UserDetail getUserDetail() { 35 return userDetail; 36 } 37 public void setUserDetail(UserDetail userDetail) { 38 this.userDetail = userDetail; 39 } 40 41 }
然后建一个配置类APPContext扫描具体的实体类包
1 package com.zhaoming.config; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 6 @Configuration //指定当前类是一个配置文件,代替原来的ApplicationContext.xml 7 @ComponentScan("com.zhaoming.annotation.entity") //指定扫描具体的包 8 public class APPContext1 { 9 10 }
测试:
1 package com.zhaoming.annocation.entity; 2 3 import org.junit.Test; 4 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 5 import com.zhaoming.annotation.entity.User; 6 import com.zhaoming.config.APPContext1; 7 import com.zhaoming.config.APPContext2; 8 9 public class GetUser { 10 @Test 11 public void testGetUser(){ 12 AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext(APPContext1.class); 13 User user = (User) appContext.getBean("user"); 14 System.out.println(user.getId()+","+user.getName()+","+user.getPassword()+","+user.getUserDetail().getAddress()); 15 } 16 17 18
如果想加另一个类的对象,新建一个实体类Userdetail
1 package com.zhaoming.annotation.entity; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5 6 @Component("userDetail") 7 public class UserDetail { 8 private int id; 9 @Value("青青草原") 10 private String address; 11 public int getId() { 12 return id; 13 } 14 public void setId(int id) { 15 this.id = id; 16 } 17 public String getAddress() { 18 return address; 19 } 20 public void setAddress(String address) { 21 this.address = address; 22 } 23 24 }
@Result这个注解直接把UserDetail引进User类中
接下来介绍纯配置的方法:
新建User和UserDetail实体类,此时,实体类里不加任何注解
然后新建config中APPContext类(使用的是@Bean这个注解)
1 package com.zhaoming.config; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import com.zhaoming.entity.User; 6 import com.zhaoming.entity.UserDetail; 7 8 @Configuration //指定当前类是一个配置文件,代替原来的ApplicationContext.xml 9 public class APPContext2 { 10 @Bean(name="user") 11 public User gerUser(){ 12 User user= new User(); 13 user.setId(2); 14 user.setName("灰太狼"); 15 user.setPassword("123"); 16 UserDetail userDetail = new UserDetail(); 17 userDetail.setAddress("狼堡"); 18 user.setUserDetail(userDetail); 19 return user; 20 } 21 }
测试方法与之前一样。
比较这两种方法:
没有谁好谁坏之分。第一种方式应用于大量使用action、service等。第二种应用于核心配置文件中。这个两种方式还有有轻微的区别的。