spring02:依赖注入与控制反转、配置文件的常见属性

第一:概念

spring配置文件中创建bean是通过反射创建的:bean中的写的class属性其实就是为反射提供.class文件,根据动态代理模式可以知道,创建的bean对象其实是代理对象(本方法+增强方法)
spring框架:管理整个项目,实现高内聚低耦合,完成事务处理
1.依赖关系:action层依赖service层,service层依赖dao层,do层依赖jdbc或者hibernate
定义:一个类需要另外一个类提供服务,在本类中建立另外一个类的引用。(spring就是维护类与类之间的关系。高内聚低耦合)
2.高内聚低耦合:高内聚:本类的所有功能都封装到本类里。低耦合:类与类之间的联系程度小
3.spring的作用是:建立对象(类)与对象(类)的关联关系,这就是反转(把创建对象和建立关关系的权利交给第三方工厂,第三方创建对象和建立连接,此时该类就等着接收就行了(被动接收),这就是依赖注入(DI)和控制反转(IoC))
我们的项目之所以耦合度高是因为上一层调用了下一层的对象
4.Spring框架称为Bean对象容器,同时建立类和类之间的关联关系(bean对象的装配),因此Spring管理整个项目,因此他的配置文件要放在src下
5.选择版本3.0,勾选第一个aop事务,第二个核心jar,第三个是持久的意思(hibernate用的),j2ee是用struts2的时候用的。
有个超链接(可以看看)
6.以前是在调用类里面创建被调用类的对象,现在是在调用类里面声明对象类的一个引用类型的属性,并由spring工厂完成new的操作(注入对象)
7.写程序的时候用不到对象,只需要声明对象属性(接口),而运行的时候会在spring中调用他的实现类
8.bean中的id相当于是个对象名,class写该类的路径(通过反射创建的对象),property(praopt)是给类里面的属性赋值,name是属性名,ref是给这个属性名一个引用(一个实现类),此时在程序运行的时候该值会自动注入到这个类的这个属性里
9.自我总结:控制反转是说把创建对象和建立对象之间依赖关系的权利交给spring工厂,因此现在是spring框架创建对象和建立对象之间的依赖关系。依赖注入是指spring框架会把对象与对象之间的依赖关系注入到那个属性里(其实就是相当于完成实例化的过程,因为我们在代码中只是声明了属性,真正赋值的过程是由spring配置文件给注入的)
10.属性必须提供set方法,因为属性是私有的,只有有了set方法,spring框架才能给这个属性注入值。
11schema是跟标签,在beans包下的xml中,这是看协议
12.在property里给属性赋值:value是用于基本数据类型和String类型的,如果是引用类型的话就使用ref
13.几种常用属性的注入方法:1.基本类型。2,引用类型。3集合
  ----1.基本类型和String用value
  ---2.如果给对象赋(注入)值的话就是ref
  ----3.property下面的子标签 如果是list就是给list集合赋值,如果是set就是个set集合赋值,如果是map就是给map集合赋值
   ---4.数组:数组集合和list集合(底层就是数组)用list标签给的属性注入值
  ---5.给set集合注入值:用set子标签
  ----6.ref中的local是在当前文件查找指定的bean,bean是在整个项目中查找指定的bean
  ---7.map属性注入:entry()恩tree
 ---8.properties这个类继承了hashtable,现在注入properties属性(这个属性就是session工厂),
14.注入空值value="",控制台输出"",注入null,控制台输出null
15.set注入其实是跟set方法的名字一样,这正好符合了反射的思想,因此property标签其实就是在做反射的事
16,生成set方法的方式叫做set注入,生成一个构造函数的方式叫做构造注入,<constructor-rag>:constructor是构造的意思,rag是参数的意思,顺序跟构造函数的形参的顺序相对应
17.常用注入方式有两种:一个set注入(先创建对象后赋值),另一个是构造注入(创建对象的时候同时赋值)。其实还有第三种是接口注入
18.自动装配模式(也叫协作者)把对象里的属性放进去:每个bean的默认情况是不自动装配autowire=no..byname是根据名字装配.
是在实体类中去找,同样在整个配置文件中去找,都找到的时候就会自动装配(自动帮我们注入,不用程序员写一句,程序员注入的话叫做手动装配)

第二:set注入代码

1.用hibernate写dao层

package com.model.dao;

import com.model.pojo.User;

public class DaoHiber implements UserDao {

 private User user;
 

 public void setUser(User user) {
  this.user = user;
 }

 public void save() {
  // TODO Auto-generated method stub
  System.out.println("hibernate-----进行了对象的保存"+user);
 }

扫描二维码关注公众号,回复: 414464 查看本文章

}

2.用jdbc写dao层

package com.model.dao;

public class DaoJDBC implements UserDao
{

 public void save()
 {
  System.out.println("jdbc-----进行了对象的保存");
 }
}

3.给上面两个方法一个公共的接口

package com.model.dao;

public interface UserDao {

 
 public void save();
}

4.service调用dao

package com.model.biz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.model.dao.UserDao;
//本类里面有两个对象,第一个是dao对象,dao对象只是声明了,但没有实例化(创建对象实例),实例化过程是在加载配置文件的时候配置文件自动帮该对象实例化的
//第二个对象是userbiz对象,我们是直接获取配置文件中的这个bean对象,执行userbiz.saveUser()的时候需要依赖dao对象,因此我们可以看到配置文件中的userbiz对象中必定存在ref属性
public class UserBiz {

 //DaoJDBC dao = new DaoJDBC();
 private UserDao dao;//在这里声明一个dao对象,然后实例化过程在配置文件中完成,这叫低耦合(控制反转),也就是把创建对象和建立对象和对象之间的依赖关系的权利交给配置文件

 
 public void setDao(UserDao dao) {
  this.dao = dao;
 }

 public void saveUser()
 {
  
  dao.save();
 }
 
 public static void main(String[] args) {
  
  /*UserBiz biz = new UserBiz();
  //biz.setDao(new DaoHiber());
  //biz.setDao(new DaoJDBC());
  biz.saveUser();*/
  
   ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
   UserBiz userbiz = (UserBiz) ac.getBean("userbiz");//这里是获得对象,获得配置文件中创建好的对象
   userbiz.saveUser();
}
}

5.spring配置文件:接口具体会调用哪个实现类,在此配置文件中写出。

<?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:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
   <bean id="dateaaa" class="java.util.Date"></bean>
   <bean id="u" class="com.model.pojo.User"><!-- 这一行表示用set注入的方式创建一个对象,此时相当于调用的空的构造函数(创建一个空的对象),当下面给各个属性赋值的时候才是调用 每个属性的set方法对这个空对象赋值,因此set注入的时候必须保证有set方法和空 的构造方法-->
        <property name="uuid" value="110"></property><!-- 给user实体类中的uid属性,由于uid属性的set方法写成了setUuid,因此这里要写uuid -->
        <property name="hobby"><!-- 给user实体类的hobby属性赋值给数组赋值的过程,由于数组的底层是list集合,因此数组和list集合都是这样赋值 -->
               <list>
                   <value>睡觉</value>
                   <value>吃饭</value>
                   <value>看电影</value>
                   <value>玩游戏</value>
               </list>
        </property>
        <property name="tset"><!-- 给user实体类的tset属性赋值,由于给属性类型是set集合,结合中的第四个元素是引用(ref)的上面一个bean对象,local属性表示在本文件中查找指定的bean对象,bean属性表示在全局范围内查找指定的bean对象-->
             <set>
                <value>xxx</value>
                <value>yyyy</value>
                <value>4444</value>
                <ref local="dateaaa"/>          
             </set>
        </property>
        <property name="map"><!--给user实体类中的map属性赋值的过程,map属性的类型是个map集合,map集合在赋值 的时候是以实体的形式一个一个赋值的 -->
            <map>
                 <entry key="k1">
                    <value>这是v1</value>
                 </entry>
                 <entry key="k2">
                    <value>这是v2</value>
                 </entry>
                 <entry key="k3">
                    <value>这是v3</value>
                 </entry>
            </map>
        </property>
        <property name="pro"><!--给user实体类中的pro属性赋值,pro属性的类型是Propertiese类型,因此Properties类型的属性要这样赋值 -->
            <props>
                 <prop key="k1">v1</prop>
                 <prop key="k2">v2</prop>
            </props>
        </property>
        <property name="date">
           <ref bean="dateaaa"/><!-- 给user实体类中的date属性赋值,这个属性依赖于上面的一个名字为dateaaa的bean对象 -->
        </property>
        <!-- 此时这个user实体类的属性中,还有一个uname属性没有赋值,所以会是null,是String类型的初始值 -->
   </bean>
   <!-- 创建dao层对象,用于依赖注入 -->
   <bean id="daoHiber" class="com.model.dao.DaoHiber">
     <property name="user" ref="u"></property><!-- property是给属性赋值,其实property的name属性对应着的是set方法后面的方法名,因此叫set注入,这种赋值方式是反射的方式,因为用到了class属性。 -->
   </bean>
    <bean id="daoJDBC" class="com.model.dao.DaoJDBC"></bean>
    <!--创建biz层对象 ,property是给这个对象的属性赋值,该属性是个接口,给他赋个实现类对象,此时userbiz对象和 daoHiber产生了依赖关系,userbiz依赖daoHiber-->
    <bean id="userbiz" class="com.model.biz.UserBiz">
      <property name="dao" ref="daoHiber"></property>
    </bean>
</beans>

第三.构造函数注入的代码

1.用jdbc写dao层

package com.model.dao;

public class DaoJDBC implements UserDao
{

 public void save()
 {
  System.out.println("jdbc-----进行了对象的保存");
 }
}

2.用hibernate写dao层

package com.model.dao;

import com.model.pojo.User;

public class DaoHiber implements UserDao {

 private User user;
 
 public User getUser() {
  return user;
 }

 public void setUser(User user) {
  this.user = user;
 }
  
 public DaoHiber() {
  super();
  // TODO Auto-generated constructor stub
 }

 //构造器注入的方法,要生成构造器
 public DaoHiber(User user)
 {
  System.out.println("=============="+user);
  this.user = user;
 }

 public void save() {
  // TODO Auto-generated method stub
  System.out.println("hibernate-----进行了对象的保存"+user);
 }

}

3.写dao层的接口

package com.model.dao;

public interface UserDao {

 
 public void save();
}

4.写service层

package com.model.biz;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.model.dao.UserDao;
public class UserBiz {

 //DaoJDBC dao = new DaoJDBC();
 private UserDao dao;

   

 public void setDao(UserDao dao) {
  this.dao = dao;
 }
 

 public UserBiz() {
  super();
  // TODO Auto-generated constructor stub
 }


 public UserBiz(UserDao dao) {
  System.out.println("=============="+dao);
  this.dao = dao;
 }

 public void saveUser()
 {
  
  dao.save();
 }
 
 public static void main(String[] args) {
  
  /*UserBiz biz = new UserBiz();
  //biz.setDao(new DaoHiber());
  //biz.setDao(new DaoJDBC());
  biz.saveUser();*/
  
   ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
   UserBiz userbiz = (UserBiz) ac.getBean("userbiz");//这里是获得对象,获得配置文件中创建好的对象
   userbiz.saveUser();
}
}

5.写spring配置文件

<?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:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  
    <bean id="dateaaa" class="java.util.Date"></bean>
   <bean id="uuu" class="com.model.pojo.User"><!--创建对象,由于下面有两个属性是通过构造器赋值的,因此user类必须有带两个参数的实体类。当user实体类中有带参构造函数的时候 ,就可以不要无参构造了,当没有带参构造函数的时候必须有有无参构造函数,因此要创建空对象-->
      <constructor-arg value="110"></constructor-arg><!-- 前面两行是给该类的前两个属性赋值的,使用的构造赋值,user因此实体类中必定存在两个参数的构造器, -->
      <constructor-arg value="张三"></constructor-arg><!--通过构造器注入是创建对象的同时给属性赋值,这两行加载完之后uuu对象里就有两个属性有值了。此时对象已经创建完毕,下面是通过set注入属性值,给该对象没赋过值的属性赋值 -->
      <property name="hobby"><!-- 给user实体类的hobby属性赋值给数组赋值的过程,由于数组的底层是list集合,因此数组和list集合都是这样赋值 -->
               <list>
                   <value>睡觉</value>
                   <value>吃饭</value>
                   <value>看电影</value>
                   <value>玩游戏</value>
               </list>
        </property>
        <property name="tset"><!-- 给user实体类的tset属性赋值,由于给属性类型是set集合,结合中的第四个元素是引用(ref)的上面一个bean对象,local属性表示在本文件中查找指定的bean对象,bean属性表示在全局范围内查找指定的bean对象-->
             <set>
                <value>xxx</value>
                <value>yyyy</value>
                <value>4444</value>
                <ref local="dateaaa"/>          
             </set>
        </property>
        <property name="map"><!--给user实体类中的map属性赋值的过程,map属性的类型是个map集合,map集合在赋值 的时候是以实体的形式一个一个赋值的 -->
            <map>
                 <entry key="k1">
                    <value>这是v1</value>
                 </entry>
                 <entry key="k2">
                    <value>这是v2</value>
                 </entry>
                 <entry key="k3">
                    <value>这是v3</value>
                 </entry>
            </map>
        </property>
        <property name="pro"><!--给user实体类中的pro属性赋值,pro属性的类型是Propertiese类型,因此Properties类型的属性要这样赋值 -->
            <props>
                 <prop key="k1">v1</prop>
                 <prop key="k2">v2</prop>
            </props>
        </property>
        <property name="date">
           <ref bean="dateaaa"/><!-- 给user实体类中的date属性赋值,这个属性依赖于上面的一个名字为dateaaa的bean对象 -->
        </property>
     </bean>
    
    
    <bean id="daoHiber" class="com.model.dao.DaoHiber">
     <property name="user" ref="uuu"></property>
   </bean>
  
  
    <bean id="daoJDBC" class="com.model.dao.DaoJDBC"></bean>
   
    <bean id="userbiz" class="com.model.biz.UserBiz">
      <property name="dao" ref="daoHiber"></property>
    </bean>
     
  

</beans>

猜你喜欢

转载自1601844782.iteye.com/blog/2276603