天天看点

Spring基础之IoC

       IoC(控制反转)就是将原来应用程序要做的事情,交给IoC容器去做。组件不是由应用程序来创建和配置,而是交给IoC容器去做。

       DI(依赖注入)IoC的具体实现,就是将调用者需要用到的类,交给容器去创建和配置,在运行期间,动态的自动填充给调用者。(军区主建,战区主战。)

       上面提到的交给IoC容器去创建和配置的对象,就是“bean”,“bean”可以是pojo,dao,service,action等等需要管理的对象。

       Spring使用工厂模式来创建bean,这个工厂类叫做BeanFactory,但我们大多时间使用它的子类ApplicationContext,用它来创建产品(即bean)。获取ApplicationContext有三种方式:ClassPathXmlApplicationContext 、FileSystemXmlApplicationContext 、XmlWebApplicationContext。

       BeanFactory和ApplicationContext的区别:

  • ApplicationContext会预先实例化,但耗内存
  • BeanFactory实例化较晚,但速度慢
  • ApplicationContext在服务启动时就会检验XML文件的正确性,不会产生装载时运行错误。
  • BeanFactory在启动时并不会检验XML文件的正确性,只有在获取bean时才会,这时有可能会出现装载错误。
  • 大多数场景使用ApplicationContext

       Bean由Sping容器管理,它有一些自己的属性,包括id,name,全限定类名,创建模式,初始化和销毁方法、自动装配模式、依赖检查模式、构造参数值、属性值、所依赖的其他bean等等

  • id是唯一标志一个bean的。在一个bean生成的过程中,如果有id,那么自然最好。如果没有设置id,只设置了name属性(name属性可以设置多个,比如: a,b,c),那么就把name属性中的第一个取出来,作为id;
  • 如果id和name都没有设置(例如@Service),那么系统会有一个默认生成id的方式,就是短类名。比如:com.abc.T.class的短类名就是T(Spring取出短类名之后会进行转化,转换成java常用的参数命名形式,比如:AtTen会被转化成atTen)
  • Spring基础之IoC

       注入方式分为三种:

  1. set注入
  2. 构造方法注入
  3. 接口注入

    下面为set注入,自动装载:

<?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.1.xsd">

<bean id="dog" class="com.wmj.autowire.Dog">
<property name="name" value="小黄"/>
<property name="age" value="3"></property>
</bean>

<bean id="master" class="com.wmj.autowire.Master" autowire="byName">
<property name="name" value="wmj"/>
</bean>
</beans>

//主人
public class Master {
private String name;
private Dog dog;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public Dog getDog() {
    return dog;
}
public void setDog(Dog dog) {
    this.dog = dog;
}
}

//宠物狗
public class Dog {
private String name;
private int age;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

}

//调用
public class App {
public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/autowire/beans.xml");
    Master master = (Master) ac.getBean("master");
    System.out.println(master.getName()+"养"+master.getDog().getName());
}
}

//运行结果
wmj养小黄
           

       继承配置:

//bean配置
<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"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean id="student" class="com.wmj.inherit.Student">
<property name="name" value="刘德华"/>
<property name="age" value="60"/>
</bean>
<bean id="graduate" parent="student" class="com.wmj.inherit.Graduate">
<property name="degree" value="学士"/>
<property name="name" value="张学友"/>
</bean>
</beans>

//学生
public class Student {
private String name;
private int age;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

//毕业生
public class Graduate extends Student{
private String degree;

public String getDegree() {
    return degree;
}

public void setDegree(String degree) {
    this.degree = degree;
}
}
}

//调用
public class App {
public static void main(String[] args) {
    BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/wmj/inherit/beans.xml"));
    Graduate gd = (Graduate) factory.getBean("graduate");
    System.out.println(gd.getName()+" "+gd.getAge()+" "+gd.getDegree());
}
}

//运行结果
张学友  学士
           

       集合注入配置配置:

<bean id="department" class="com.wmj.collection.Department">
<property name="name" value="技术部"/>
<!-- 配置properties -->
<property name="pp">
<props>
<prop key="pp1"></prop>
<prop key="pp2"></prop>
</props>
</property>
<!-- 给数组注入值 -->
<property name="empname">
<list>
<value>小明</value>
<value>大明</value>
<value>老明</value>
</list>
</property>
<!-- 给list注入值 -->
<property name="emplist">
<list>
<ref bean="emp1"/>
<ref bean="emp2"/>
</list>
</property>
<!-- 给set注入值 -->
<property name="empset">
<set>
<ref bean="emp1"/>
<ref bean="emp2"/>
</set>
</property>
<!-- 给map注入值 -->
<property name="empmap">
<map>
<entry key="1" value-ref="emp1"/>
<entry key="2" value-ref="emp2"/>
</map>
</property>
</bean>

<!-- 也可以通过构造函数注入 -->
<bean id="emp3" class="com.wmj.collection.Employee">
<constructor-arg index="0" type="java.lang.String" value="杰哥"/>
<constructor-arg index="1" type="java.lang.Integer" value="22"/>
</bean>
<bean id="emp1" class="com.wmj.collection.Employee">
<property name="name" value="奥巴马"/>
<property name="age" value="60"/>
</bean>
<bean id="emp2" class="com.wmj.collection.Employee">
<property name="name" value="卡梅伦"/>
<property name="age" value="65"/>
</bean>

public class Department {
private String name;
private String[] empname;
private List<Employee> emplist;
private Set<Employee> empset;
private Map<String,Employee> empmap;
private Properties pp;

public Properties getPp() {
    return pp;
}
public void setPp(Properties pp) {
    this.pp = pp;
}
public Map<String, Employee> getEmpmap() {
    return empmap;
}
public void setEmpmap(Map<String, Employee> empmap) {
    this.empmap = empmap;
}
public Set<Employee> getEmpset() {
    return empset;
}
public void setEmpset(Set<Employee> empset) {
    this.empset = empset;
}
public List<Employee> getEmplist() {
    return emplist;
}
public void setEmplist(List<Employee> emplist) {
    this.emplist = emplist;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String[] getEmpname() {
    return empname;
}
public void setEmpname(String[] empname) {
    this.empname = empname;
}
}

public class Employee {
private String name;
private int age;

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Employee(String name, int age) {
    super();
    this.name = name;
    this.age = age;
}
public Employee(){

}
}

public class App {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
    ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/collection/beans.xml");
    Department dm = (Department) ac.getBean("department");
    System.out.println(dm.getName());
    for(String ename: dm.getEmpname()){
        System.out.println(ename);
    }
    System.out.println("*************通过list取数据********************");
    for(Employee emp: dm.getEmplist()){
          System.out.println(emp.getName());    
    }
    System.out.println("*************通过set取数据********************");
    for(Employee emp: dm.getEmpset()){
          System.out.println(emp.getName());    
    }
    System.out.println("*************通过map取数据********************");
    //通过entry取
    for(Entry<String,Employee> emp:dm.getEmpmap().entrySet()){
        System.out.println(emp.getKey()+" "+emp.getValue().getName());
    }
    //通过iterator迭代器取数据
    Map<String,Employee> empmap = dm.getEmpmap();
    Iterator it =  (Iterator) empmap.keySet().iterator();
    while(it.hasNext()){
        String key = (String) it.next();
        Employee emp = empmap.get(key);
        System.out.println("key="+key+" value="+emp.getName()+" "+emp.getAge());
    }
    System.out.println("*************通过properties取数据********************");
    Properties pp = dm.getPp();
    for(Entry<Object,Object> entry: pp.entrySet()){
     System.out.println(entry.getKey().toString()+" "+entry.getValue().toString());
    }
    System.out.println("*************通过Enumeration取数据********************");
    Enumeration en = pp.keys();
    while(en.hasMoreElements()){
        String key = (String) en.nextElement();
        System.out.println(key+" "+pp.getProperty(key));
    }
    }

}
           

       bean可以配置多种类型的对象,例如数据源,action,ftp服务器,邮件服务器等等,下面以配置简单数据源作为栗子。

<?xml version="1.0" encoding="utf-8"?>
<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<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"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!--引入db.properties文件  -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>com/wmj/dispacher/db.properties</value>
</list>
</property>
</bean>
<bean id="dbutil" class="com.wmj.dispacher.DBUtil">
<property name="drivername" value="${drivername}"/>
<property name="url" value="${url}"/>
<property name="name" value="${name}"/>
<property name="pwd" value="${pwd}"/>
</bean>
</beans>

public class DBUtil {
private String drivername;
private String url;
private String name;
private String pwd;
public String getDrivername() {
    return drivername;
}
public void setDrivername(String drivername) {
    this.drivername = drivername;
}
public String getUrl() {
    return url;
}
public void setUrl(String url) {
    this.url = url;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getPwd() {
    return pwd;
}
public void setPwd(String pwd) {
    this.pwd = pwd;
}

}

//文件db.properties
drivername=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/xuanke
name=root
pwd=940130

public class App {
public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/dispacher/beans.xml");
    DBUtil db = (DBUtil) ac.getBean("dbutil");
    System.out.println(db.getDrivername()+"  "+db.getName());
}
}