欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring基础之IoC

程序员文章站 2022-07-12 12:58:46
...

       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());
}
}

//运行结果
张学友 60 学士

       集合注入配置配置:

<bean id="department" class="com.wmj.collection.Department">
<property name="name" value="技术部"/>
<!-- 配置properties -->
<property name="pp">
<props>
<prop key="pp1">1111</prop>
<prop key="pp2">2222</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());
}
}