前言
  在Spring的第二篇中主要讲解了Spring Core模块的使用IOC容器创建对象的问题,Spring Core模块主要是解决对象的创建和对象之间的依赖关系,因此本博文主要讲解如何使用IOC容器来解决对象之间的依赖关系!
   回顾以前对象依赖
  我们来看一下我们以前关于对象依赖,是怎么的历程
   直接new对象
     - 在最开始,我们是直接new对象给serice的userDao属性赋值...
 class  UserService{ 	UserDao userDao = new UserDao(); }  
   写DaoFactory,用字符串来维护依赖关系
     public class DaoFactory {      private static final DaoFactory factory = new DaoFactory();     private DaoFactory(){}      public static DaoFactory getInstance(){         return factory;     }      public <T> T createDao(String className,Class<T> clazz){         try{             T t = (T) Class.forName(className).newInstance();             return t;         }catch (Exception e) {             throw new RuntimeException(e);         }     }  }  
        private CategoryDao categoryDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.CategoryDAOImpl", CategoryDao.class);      private BookDao bookDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.BookDaoImpl", BookDao.class);      private UserDao userDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.UserDaoImpl", UserDao.class);      private OrderDao orderDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.OrderDaoImpl", OrderDao.class);  
   DaoFactory读取配置文件
      public class DaoFactory { 	 	private  UserDao userdao = null; 	 	private DaoFactory(){ 		try{ 			InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties"); 			Properties prop = new Properties(); 			prop.load(in); 			 			String daoClassName = prop.getProperty("userdao"); 			userdao = (UserDao)Class.forName(daoClassName).newInstance(); 			 		}catch (Exception e) { 			throw new RuntimeException(e); 		} 	} 	 	private static final DaoFactory instance = new DaoFactory(); 	 	public static DaoFactory getInstance(){ 		return instance; 	} 	 	 	public UserDao createUserDao(){ 		return userdao; 	} 	 }  
    	UserDao dao = DaoFactory.getInstance().createUserDao(); 
   Spring依赖注入
  通过上面的历程,我们可以清晰地发现:对象之间的依赖关系,其实就是给对象上的属性赋值!因为对象上有其他对象的变量,因此存在了依赖...
  Spring提供了好几种的方式来给属性赋值
     - 1) 通过构造函数
- 2) 通过set方法给属性注入值
-          - p名称空间
 
- 4)自动装配(了解)
- 5) 注解
搭建测试环境
    public class UserDao {  	public void save() { 		System.out.println("DB:保存用户"); 	} }  
     public class UserService { 	 	private UserDao userDao;   	public void save() { 		userDao.save(); 	} }  
    public class UserAction {  	private UserService userService;  	public String execute() { 		userService.save(); 		return null; 	} } 
   构造函数给属性赋值
  其实我们在讲解创建带参数的构造函数的时候已经讲过了...我们还是来回顾一下呗..
  我们测试service和dao的依赖关系就好了....在serice中加入一个构造函数,参数就是userDao
      public UserService(UserDao userDao) {         this.userDao = userDao; 		 		//看看有没有拿到userDao 		System.out.println(userDao);     }  
  applicationContext.xml配置文件
       <!--创建userDao对象-->     <bean id="userDao" class="UserDao"/>      <!--创建userService对象-->     <bean id="userService" class="UserService">         <!--要想在userService层中能够引用到userDao,就必须先创建userDao对象-->         <constructor-arg index="0" name="userDao" type="UserDao" ref="userDao"></constructor-arg>     </bean>  
             // 创建容器对象         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");          //得到service对象         UserService userService = (UserService) ac.getBean("userService"); 
   
  
   
   通过set方法给属性注入值
  我们这里也是测试service和dao层的依赖关系就好了...在service层通过set方法来把userDao注入到UserService中
     public class UserService {      private UserDao userDao;       public void setUserDao(UserDao userDao) {         this.userDao = userDao;          //看看有没有拿到userDao         System.out.println(userDao);     }      public void save() {         userDao.save();     } }  
  applicationContext.xml配置文件:通过property节点来给属性赋值
     - 引用类型使用ref属性
- 基本类型使用value属性
     <!--创建userDao对象-->     <bean id="userDao" class="UserDao"/>      <!--创建userService对象-->     <bean id="userService" class="UserService">         <property name="userDao" ref="userDao"/>     </bean>  
     
  
   
   内部Bean
  我们刚才是先创建userDao对象,再由userService对userDao对象进行引用...我们还有另一种思维:先创建userService,发现userService需要userDao的属性,再创建userDao...我们来看看这种思维方式是怎么配置的:
  applicationContext.xml配置文件:property节点内置bean节点
       <!--         1.创建userService,看到有userDao这个属性         2.而userDao这个属性又是一个对象         3.在property属性下又内置了一个bean         4.创建userDao     -->     <bean id="userService" class="UserService">         <property name="userDao">             <bean id="userDao" class="UserDao"/>         </property>     </bean>   
     
  
   
  我们发现这种思维方式和服务器访问的执行顺序是一样的,但是如果userDao要多次被其他service使用的话,就要多次配置了...
   p 名称空间注入属性值
  p名称控件这种方式其实就是set方法的一种优化,优化了配置而已...p名称空间这个内容需要在Spring3版本以上才能使用...我们来看看:
  applicationContext.xml配置文件:使用p名称空间
       <bean id="userDao" class="UserDao"/>          <!--不用写property节点了,直接使用p名称空间-->     <bean id="userService" class="UserService" p:userDao-ref="userDao"/>  
     
  
   
   自动装配
  Spring还提供了自动装配的功能,能够非常简化我们的配置
  自动装载默认是不打开的,自动装配常用的可分为两种:
     XML配置根据名字
  applicationContext.xml配置文件:使用自动装配,根据名字
       <bean id="userDao" class="UserDao"/>      <!--         1.通过名字来自动装配         2.发现userService中有个叫userDao的属性         3.看看IOC容器中没有叫userDao的对象         4.如果有,就装配进去     -->     <bean id="userService" class="UserService" autowire="byName"/>  
     
  
   
   XML配置根据类型
  applicationContext.xml配置文件:使用自动装配,根据类型
  值得注意的是:如果使用了根据类型来自动装配,那么在IOC容器中只能有一个这样的类型,否则就会报错!
       <bean id="userDao" class="UserDao"/>      <!--         1.通过名字来自动装配         2.发现userService中有个叫userDao的属性         3.看看IOC容器UserDao类型的对象         4.如果有,就装配进去     -->     <bean id="userService" class="UserService" autowire="byType"/>  
     
  
   
  我们这只是测试两个对象之间的依赖关系,如果我们有很多对象,我们也可以使用默认自动分配
   
  
   
  ###使用注解来实现自动装配###
  @Autowired注解来实现自动装配:
     - 可以在构造器上修饰
- 也可以在setter方法上修饰
- 来自java的@Inject的和@AutoWired有相同的功能
如果没有匹配到bean,又为了避免异常的出现,我们可以使用required属性上设置为false。【谨慎对待】
    @Component public class UserService {      private UserDao userDao ;       @Autowired     public void setUserDao(UserDao userDao) {         this.userDao = userDao;     } } 
  顺利拿到userDao的引用
   
  
   
   使用JavaConfig配置类实现对象依赖
  在有两种方法(但我测试不出来,如果会的请在评论去告诉我.....)
     import org.springframework.context.annotation.Bean;  @org.springframework.context.annotation.Configuration public class Configuration {      @Bean()     public UserDao userDao() {          return new UserDao();     }      @Bean     public UserService userService() {          //直接调用@bean的方法         return new UserService(userDao());     }  } 
     import org.springframework.context.annotation.Bean;  @org.springframework.context.annotation.Configuration public class Configuration {      @Bean()     public UserDao userDao() {          return new UserDao();     }      @Bean     public UserService userService(UserDao userDao) {          //通过构造函数依赖注入         return new UserService(userDao);     }  }  
   
  
   
     import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean;  @org.springframework.context.annotation.Configuration public class Configuration {      @Bean()     public UserDao userDao() {          return new UserDao();     }      @Bean(autowire = Autowire.BY_TYPE)     public UserService userService(UserDao userDao) {          return new UserService(userDao);     }  } 
   
  
   
     - 我测试中只有通过这种方法才能拿到userDao的引用。
public class Configuration {      @Bean()     public UserDao userDao() {          return new UserDao();     }      @Bean(autowire = Autowire.BY_TYPE)     public UserService userService() {          return new UserService(userDao());     }  }   
   
  
   
  当然了,最简单直观的方法还有一种:在UserService中加入setUser()方法,那么只要set进去就行了..
     public class UserService {      private UserDao userDao ;      public UserService() {     }      public UserService(UserDao userDao) {       }      public void setUserDao(UserDao userDao) {         this.userDao = userDao;     } } 
     import org.springframework.context.annotation.Bean;  @org.springframework.context.annotation.Configuration public class Config1 {      @Bean(name = "userDao")     public UserDao userDao() {          return new UserDao();     }       @Bean(name="userService")     public UserService userService() {          UserService userService = new UserService();          userService.setUserDao(userDao());          return userService;     }  } 
   
  
   
   最后
  扩展阅读:
       如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y