Spring DI

来源:互联网 发布:通过ip查mac地址命令 编辑:程序博客网 时间:2024/04/24 16:16

在Spring中通过xml配置实现DI

beans.xml

<?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:util="http://www.springframework.org/schema/util"    xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">    <!-- 配置一个 bean -->    <bean id="helloWorld" class="com.shan.spring.helloworld.HelloWorld">        <!-- 为属性赋值 -->        <property name="user" value="Jerry"></property>    </bean>    <!-- 配置一个 bean -->    <bean id="helloWorld2" class="com.shan.spring.helloworld.HelloWorld">        <!-- 为属性赋值 -->        <!-- 通过属性注入: 通过 setter 方法注入属性值 -->        <property name="user" value="Tom"></property>    </bean>    <!-- 通过构造器注入属性值 -->    <bean id="helloWorld3" class="com.shan.spring.helloworld.HelloWorld">        <!-- 要求: 在 Bean 中必须有对应的构造器.  -->        <constructor-arg value="Mike"></constructor-arg>    </bean>    <!-- 若一个 bean 有多个构造器, 如何通过构造器来为 bean 的属性赋值 -->    <!-- 可以根据 index 和 value 进行更加精确的定位. (了解) -->    <bean id="car" class="com.shan.spring.helloworld.Car">        <constructor-arg value="KUGA" index="1"></constructor-arg>        <constructor-arg value="ChangAnFord" index="0"></constructor-arg>        <constructor-arg value="250000" type="float"></constructor-arg>    </bean>    <bean id="car2" class="com.shan.spring.helloworld.Car">        <constructor-arg value="ChangAnMazda"></constructor-arg>        <!-- 若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值. (了解) -->        <constructor-arg>            <value><![CDATA[<ATARZA>]]></value>        </constructor-arg>        <constructor-arg value="180" type="int"></constructor-arg>    </bean>    <!-- 配置 bean -->    <bean id="dao5" class="com.shan.spring.ref.Dao"></bean>    <bean id="service" class="com.shan.spring.ref.Service">        <!-- 通过 ref 属性值指定当前属性指向哪一个 bean! -->        <property name="dao" ref="dao5"></property>    </bean>    <!-- 声明使用内部 bean -->    <bean id="service2" class="com.shan.spring.ref.Service">        <property name="dao">            <!-- 内部 bean, 类似于匿名内部类对象. 不能被外部的 bean 来引用, 也没有必要设置 id 属性 -->            <bean class="com.shan.spring.ref.Dao">                <property name="dataSource" value="c3p0"></property>            </bean>        </property>    </bean>    <bean id="action" class="com.shan.spring.ref.Action">        <property name="service" ref="service2"></property>        <!-- 设置级联属性(了解) -->        <property name="service.dao.dataSource" value="DBCP2"></property>    </bean>    <bean id="dao2" class="com.shan.spring.ref.Dao">        <!-- 为 Dao 的 dataSource 属性赋值为 null, 若某一个 bean 的属性值不是 null, 使用时需要为其设置为 null(了解) -->        <property name="dataSource"><null/></property>    </bean>    <!-- 装配集合属性 -->    <bean id="user" class="com.shan.spring.helloworld.User">        <property name="userName" value="Jack"></property>        <property name="cars">            <!-- 使用 list 元素来装配集合属性 -->            <list>                <ref bean="car"/>                <ref bean="car2"/>            </list>        </property>    </bean>    <!-- 声明集合类型的 bean -->    <util:list id="cars">        <ref bean="car"/>        <ref bean="car2"/>    </util:list>    <bean id="user2" class="com.shan.spring.helloworld.User">        <property name="userName" value="Rose"></property>        <!-- 引用外部声明的 list -->        <property name="cars" ref="cars"></property>    </bean>    <bean id="user3" class="com.shan.spring.helloworld.User"        p:cars-ref="cars" p:userName="Titannic"></bean>    <!-- bean 的配置能够继承吗 ? 使用 parent 来完成继承 -->    <bean id="user4" parent="user" p:userName="Bob"></bean>    <bean id="user6" parent="user" p:userName="维多利亚"></bean>    <!-- 测试 depents-on -->    <bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean></beans>

在 main 函数中的测试代码

package com.shan.spring.helloworld;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {    public static void main(String[] args) {//        HelloWorld helloWorld = new HelloWorld();//        helloWorld.setUser("Tom");//        helloWorld.hello();        //1. 创建 Spring 的 IOC 容器        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");        //2. 从 IOC 容器中获取 bean 的实例        HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld3");        //根据类型来获取 bean 的实例: 要求在  IOC 容器中只有一个与之类型匹配的 bean, 若有多个则会抛出异常.        //一般情况下, 该方法可用, 因为一般情况下, 在一个 IOC 容器中一个类型对应的 bean 也只有一个.//        HelloWorld helloWorld1 = ctx.getBean(HelloWorld.class);        //3. 使用 bean        helloWorld.hello();        Car car = (Car) ctx.getBean("car");        System.out.println(car);        Car car2 = (Car) ctx.getBean("car2");        System.out.println(car2);        //4. 测试使用集合属性        User user = (User) ctx.getBean("user5");        System.out.println(user);    }}

使用 Junit 测试

package org.test.di;import com.shan.spring.helloworld.Car;import com.shan.spring.helloworld.HelloWorld;import com.shan.spring.helloworld.User;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.annotation.Resource;/** * Created by shan on 2016/2/20. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:beans.xml")public class TestDi {    @Resource(name="helloWorld2")    private HelloWorld helloWorld;    @Resource(name="car")    private Car car;    @Resource(name="car2")    private Car car2;    @Resource(name = "user5")    private User user5;    /**     * helloworld     */    @Test    public void testDiWithXmlConf(){        System.out.println("---begin--");        helloWorld.hello();        System.out.println(car);        System.out.println(car2);        System.out.println(user5);        System.out.println("---end--");    }}

HelloWorld.java

package com.shan.spring.helloworld;public class HelloWorld {    private String user;    public HelloWorld() {        System.out.println("HelloWorld's constructor...");    }    public void setUser(String user) {        System.out.println("setUser:" + user);        this.user = user;    }    public HelloWorld(String user) {        this.user = user;    }    public void hello(){        System.out.println("Hello: " + user);    }}

User.java

package com.shan.spring.helloworld;import java.util.List;public class User {    private String userName;    private List<Car> cars;    private String wifeName;    public String getWifeName() {        return wifeName;    }    public void setWifeName(String wifeName) {        System.out.println("setWifhName: " + wifeName);        this.wifeName = wifeName;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public List<Car> getCars() {        return cars;    }    public void setCars(List<Car> cars) {        this.cars = cars;    }    public User() {        System.out.println("User's Construtor...");    }    @Override    public String toString() {        return "User [userName=" + userName + ", cars=" + cars + "]";    }    public void init(){        System.out.println("init method...");    }    public void destroy(){        System.out.println("destroy method...");    }}

Car.java

package com.shan.spring.helloworld;public class Car {    private String company;    private String brand;    private int maxSpeed;    private float price;    public Car(String company, String brand, float price) {        super();        this.company = company;        this.brand = brand;        this.price = price;    }    public Car(String company, String brand, int maxSpeed) {        super();        this.company = company;        this.brand = brand;        this.maxSpeed = maxSpeed;    }    public Car(String company, String brand, int maxSpeed, float price) {        super();        this.company = company;        this.brand = brand;        this.maxSpeed = maxSpeed;        this.price = price;    }    @Override    public String toString() {        return "Car [company=" + company + ", brand=" + brand + ", maxSpeed="                + maxSpeed + ", price=" + price + "]";    }}

在Spring通过自动装配实现DI

beans-auto.xml

<?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:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">    <!-- 自动装配: 只声明 bean, 而把 bean 之间的关系交给 IOC 容器来完成 -->    <!--        byType: 根据类型进行自动装配. 但要求 IOC 容器中只有一个类型对应的 bean, 若有多个则无法完成自动装配.        byName: 若属性名和某一个 bean 的 id 名一致, 即可完成自动装配. 若没有 id 一致的, 则无法完成自动装配    -->    <!-- 在使用 XML 配置时, 自动转配用的不多. 但在基于 注解 的配置时, 自动装配使用的较多.  -->    <bean id="dao" class="com.shan.spring.ref.Dao">        <property name="dataSource" value="C3P0"></property>    </bean>    <!-- 默认情况下 bean 是单例的! -->    <!-- 但有的时候, bean 就不能使单例的. 例如: Struts2 的 Action 就不是单例的! 可以通过 scope 属性来指定 bean 的作用域 -->    <!--        prototype: 原型的. 每次调用 getBean 方法都会返回一个新的 bean. 且在第一次调用 getBean 方法时才创建实例        singleton: 单例的. 每次调用 getBean 方法都会返回同一个 bean. 且在 IOC 容器初始化时即创建 bean 的实例. 默认值    -->    <bean id="dao2" class="com.shan.spring.ref.Dao" scope="prototype"></bean>    <bean id="service" class="com.shan.spring.ref.Service" autowire="byName"></bean>    <bean id="action" class="com.shan.spring.ref.Action" autowire="byType"></bean>    <!-- 导入外部的资源文件 -->    <context:property-placeholder location="classpath:db.properties"/>    <!-- 配置数据源 -->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="user" value="${jdbc.user}"></property>        <property name="password" value="${jdbc.password}"></property>        <property name="driverClass" value="${jdbc.driverClass}"></property>        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>    </bean>    <!-- 测试 SpEL: 可以为属性进行动态的赋值(了解) -->    <bean id="girl" class="com.shan.spring.helloworld.User">        <property name="userName" value="周迅"></property>    </bean>    <bean id="boy" class="com.shan.spring.helloworld.User" init-method="init" destroy-method="destroy">        <property name="userName" value="高胜远"></property>        <property name="wifeName" value="#{girl.userName}"></property>    </bean>    <!-- 配置 bean 后置处理器: 不需要配置 id 属性, IOC 容器会识别到他是一个 bean 后置处理器, 并调用其方法 -->    <bean class="com.shan.spring.ref.MyBeanPostProcessor"></bean>    <!-- 通过工厂方法的方式来配置 bean -->    <!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->    <!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->    <bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">        <!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->        <constructor-arg value="2"></constructor-arg>    </bean>    <!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->    <!-- ①. 创建工厂对应的 bean -->    <bean id="simpleDateFormat" class="java.text.SimpleDateFormat">        <constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>    </bean>    <!-- ②. 有实例工厂方法来创建 bean 实例 -->    <!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->    <bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">        <!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->        <constructor-arg value="1990-12-12 12:12:12"></constructor-arg>    </bean>    <!-- 配置通过 FactroyBean 的方式来创建 bean 的实例(了解) -->    <bean id="user" class="com.shan.spring.ref.UserBean"></bean></beans>

在mian 函数中测试

package com.shan.spring.ref;import java.sql.SQLException;import java.text.DateFormat;import java.util.Date;import javax.sql.DataSource;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.shan.spring.helloworld.User;public class Main {    public static void main(String[] args) throws SQLException {        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-auto.xml");        Action action = ctx.getBean(Action.class);        action.execute();        //测试 bean 的作用域        Dao dao1 = (Dao) ctx.getBean("dao2");        Dao dao2 = (Dao) ctx.getBean("dao2");        System.out.println(dao1 == dao2);        //测试使用外部属性文件        DataSource dataSource = (DataSource) ctx.getBean("dataSource");        System.out.println(dataSource.getConnection());        //测试 spEL        User boy = (User) ctx.getBean("boy");        System.out.println(boy.getUserName() + ":" + boy.getWifeName());//      DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL);        DateFormat dateFormat = (DateFormat) ctx.getBean("dateFormat");        System.out.println(dateFormat.format(new Date()));        Date date = (Date) ctx.getBean("datetime");        System.out.println(date);        User user = (User) ctx.getBean("user");        System.out.println(user);        ctx.close();    }}

在 Junit中测试

package org.test.di;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.annotation.Resource;import javax.sql.DataSource;import java.sql.SQLException;/** * Created by shan on 2016/2/20. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"classpath:beans-auto.xml"})public class testAutoDi {    @Resource(name = "dataSource")    private DataSource dataSource;    @Test    public  void testAutoConf(){        try {            System.out.println("datasource :" + dataSource.getConnection());        } catch (SQLException e) {            e.printStackTrace();        }    }}

Action.java

package com.shan.spring.ref;public class Action {    private Service service;    public void setService(Service service) {        this.service = service;    }    public Service getService() {        return service;    }    public void execute(){        System.out.println("Action's execute...");        service.save();    }}

Dao.java

package com.shan.spring.ref;public class Dao {    private String dataSource = "dbcp";    public void setDataSource(String dataSource) {        this.dataSource = dataSource;    }    public void save(){        System.out.println("save by " + dataSource);    }    public Dao() {        System.out.println("Dao's Constructor...");    }}

UserBean.java

““java
package com.shan.spring.ref;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.FactoryBean;

import com.shan.spring.helloworld.Car;
import com.shan.spring.helloworld.User;

public class UserBean implements FactoryBean{

/** * 返回的 bean 的实例 */@Overridepublic User getObject() throws Exception {    User user = new User();    user.setUserName("abc");    user.setWifeName("ABC");    List<Car> cars = new ArrayList<Car>();    cars.add(new Car("ShangHai", "BuiKe", 180, 300000));    cars.add(new Car("ShangHai", "CRUZE", 130, 150000));    user.setCars(cars);    return user;}/** * 返回的 bean 的类型 */@Overridepublic Class<?> getObjectType() {    return User.class;}/** * 返回的 bean 是否为单例的 */@Overridepublic boolean isSingleton() {    return true;}

}

MyBeanPostProcessor.java

“`java
package com.shan.spring.ref;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import com.shan.spring.helloworld.User;

public class MyBeanPostProcessor implements BeanPostProcessor {

//该方法在 init 方法之后被调用@Overridepublic Object postProcessAfterInitialization(Object arg0, String arg1)        throws BeansException {    if(arg1.equals("boy")){        System.out.println("postProcessAfterInitialization..." + arg0 + "," + arg1);        User user = (User) arg0;        user.setUserName("李大齐");    }    return arg0;}//该方法在 init 方法之前被调用//可以工作返回的对象来决定最终返回给 getBean 方法的对象是哪一个, 属性值是什么/** * @param arg0: 实际要返回的对象 * @param arg1: bean 的 id 值 */@Overridepublic Object postProcessBeforeInitialization(Object arg0, String arg1)        throws BeansException {    if(arg1.equals("boy"))        System.out.println("postProcessBeforeInitialization..." + arg0 + "," + arg1);    return arg0;}

}

Service.java

“`java
package com.shan.spring.ref;

public class Service {

private Dao dao;public void setDao(Dao dao) {    this.dao = dao;}public Dao getDao() {    return dao;}public void save(){    System.out.println("Service's save");    dao.save();}

}
““

0 0
原创粉丝点击