Spring Framework IoC以及DI的初步理解和实现

Spring Framework IoC以及DI的理解和实现(一)—–> 通过配置xml

咳咳,最近一周接触到了Spring。觉得记下来很快就会忘记,于是乎加上从网上查到的一些资料……废话就不说了

首先需要了解一下什么是IoC和DI还有bean

IoC(Inversion of Control):控制反转,就是通过容器来创建对象,对象的创建由程序自己控制,而不是以以往硬编码的方式来创建依赖关系。
DI:依赖注入,都说是IOC的一种实现方式,是实现IoC的一个过程。就是将依赖对象的创建和绑定转移到被依赖对象类的外部来实现(这句话抄来的)。
bean:在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化,组装和以其他方式管理的对象。否则,bean只是应用程序中的许多对象之一。Bean和它们之间的依赖关系反映在容器使用的配置元数据中。

First

首先要把Spring套用到项目中,在你的项目里要加入两个配置文件。我使用了maven,于是乎就把这两个配置文件放在一个新建的Source Folder下面了。
1.名为log4j.properties的日志文件配置,如果你已经有这个文件的话就把以下配置加进去,没有的话就新建一个。导包什么的就不再说了。

log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
log4j.category.org.springframework.beans.factory=INFO

2.然后需要建立一个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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">
       <!-- collaborators and configuration for this bean go here -->
    </bean>

</beans>

The bean definition(bean的定义)

PropertyExplained in…​
class要指定一个实际类
id/name唯一且遵守bean命名约定
scope不设定则默认为singleton,单例
constructor arguments体现继承关系,如果没有就不用
properties“Dependency Injection”
autowiring mode“Autowiring collaborators”
lazy-initialization mode“Lazy-initialized beans”
initialization method“Initialization callbacks”
destruction method“Initialization callbacks”

通过配置xml方式实现IoC和DI

IoC容器图示:(官网上的.......)
由图看出,IoC需要读取“元数据”,这里xml配置就相当于“元数据”。

First

假设我们要处理学生信息的管理,首先我们先写好Student类,和StudentDao实现层接口和StudentDaoImpl实现类,以及StudentBiz业务层接口和StudentBizImpl业务层实现类。
1.Student类我就不详细写了……(包含了Student 的id,sname 以及get,set方法和有参、无参的构造方法…..)
2.StudentDao接口如下:

import com.yc.bean.Student;
public interface StudentDao {   
    public void addStudent(Student student);          //添加学生信息
    public boolean isStudentExist(Student student);   //查看此学生信息是否已经存在
}

3.StudentDaoImpl实现类如下:

import java.util.Random;
import com.yc.bean.Student;
import com.yc.dao.StudentDao;

public class StudentDaoImpl implements StudentDao {
    public StudentDaoImpl() {
        System.out.println("StudentDaoImpl构造方法...");
    }
    @Override
    public void addStudent(Student student) {
        System.out.println("在StudentDaoImpl添加"+student+"...");
    }
    @Override
    public boolean isStudentExist(Student student) {
        Random r = new Random();
        return r.nextBoolean();
    }
}

4.StudentBiz业务层接口如下:

import com.yc.bean.Student;
public interface StudentBiz {
    public void addStudent(Student student); 
}

5.StudentBizImpl业务层实现如下:

import com.yc.bean.Student;
import com.yc.biz.StudentBiz;
import com.yc.dao.StudentDao;

public class StudentBizImpl implements StudentBiz {
    private StudentDao studentDao;  
    public StudentBizImpl() {
        System.out.println("StudentBizImpl构造方法...");
    }
    @Override
    public void addStudent(Student student) {
        if(studentDao.isStudentExist(student)){
            throw new RuntimeException("学生已经存在不能再添加");
        }
        studentDao.addStudent(student);
    }
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
        System.out.println("spring还偷偷的将studentDao对象注入到StudentBizImpl中...");
    }
}
Second

然后在beans.xml里就可以写入

<bean id="student" class="所在包名.Student"></bean>
//配置Bean,spring容器就可以创建对象

然后再跑到测试类里测试一下:

public class AppTest extends TestCase{ 
    public AppTest( String testName ){
        super( testName );
    }
    public static Test suite(){
        return new TestSuite( AppTest.class );
    }

    public void testApp(){
        //实例化容器,spring要在自己创建的时候,就读取beans.xml并通过反射机制创建对象,这里可以添加多个配置文  件"beans.xml","XXX.xml"逗号隔开。
       ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
       //ApplicationContext是BeanFactory的子接口,代表Spring IoC容器,并负责实例化,配置和组装上述bean。
       //而BeanFactory是一个非常强大的接口,提供了能够管理任何类型的对象的高级配置机制。

       //再从容器中取出bean
       Student student = (Student)context.getBean("student");    //这里的student,就是beans.xml里的id
       student.setId(1);
       student.setSname("张三");
       System.out.println(student);       
       Student s2 = (Student)context.getBean("student");         //再创建一个学生对象
       System.out.println(student.hashCode()+"\t"+s2.hashCode());//通过比较结果判断是单例还是多例         
    }
运行结果:
Student构造方法...
Student [id=1, sname=章㤾]
5892322 5892322
然后我们可以得出一个结论,spring创建的是单例
Third

然后我们对beans.xml继续写,实现DI

  <!--通过spring IOC创建 dao-->
    <bean id="studentDao" class="所在包.StudentDaoImpl"></bean>

  <!--通过spring IOC创建 biz-->
    <bean id="studentBiz" class="所在包.StudentBizImpl">
        <property name="studentDao" ref="studentDao"></property>   
        //关于这里的配置我是这样理解的:业务层依赖于实现层,通过调用业务层就可以实现调用实层的方法,id和ref体现了依赖关系
    </bean>

然后跑到测试类测试一下:

 public void testApp2(){        
       ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});      
       Student student = (Student)context.getBean("student");
       student.setId(1);
       student.setSname("张三");
       StudentBiz sb = (StudentBiz)context.getBean("studentBiz");       
       sb.addStudent(student);
    }
运行结果:
Student构造方法...
StudentDaoImpl构造方法...
StudentBizImpl构造方法...
spring还偷偷的将studentDao对象注入到StudentBizImpl中...
在StudentDaoImpl添加Student [id=1, sname=张三]...
关于构造方法DI的栗子
public class ConstructorDi {
    private Integer x;     //苹果的编号
    private String y;      //苹果的说明
    private Apple apple;   //苹果他自己

    public ConstructorDi(Integer x, String y, Apple apple) {
        super();
        this.x = x;
        this.y = y;
        this.apple = apple;
    }
    public ConstructorDi() {
    }
    @Override
    public String toString() {
        return "ConstructorDi [x=" + x + ", y=" + y + ", apple=" + apple + "]";
    }
}

接着beans.xml:

 <!-- 构造方法di -->
    <bean id="cd" class="所在包名.ConstructorDi">
        <!--  这是第一种写法
        <constructor-arg value="77"/>
        <constructor-arg value="appleSister"/>
        <constructor-arg ref="apple"/>
         -->
         <!--这是第二种写法
         <constructor-arg name="x" value="77"/>
        <constructor-arg name="y" value="appleSister"/>
        <constructor-arg name="apple" ref="apple"/>
         -->
         <!--第三种写法 -->
        <constructor-arg index="0" value="77"/>
        <constructor-arg index="1" value="appleSister"/>
        <constructor-arg index="2" ref="apple"/>
    </bean>

去测试类瞧瞧:

public void testApp(){
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
        ConstructorDi cd = (ConstructorDi) context.getBean("cd");
        System.out.println(cd);
    }

运行结果:

ConstructorDi [x=77, y=appleSisiter, apple=Apple [aid=null]]
基于SetterDI的栗子
public class FavoriteBiz {
    private TagDao tagDao;
    private FavoriteDao favoriteDao;
    public TagDao getTagDao() {
        return tagDao;
    }
    public void setTagDao(TagDao tagDao) {
        this.tagDao = tagDao;
    }
    public FavoriteDao getFavoriteDao() {
        return favoriteDao;
    }
    public void setFavoriteDao(FavoriteDao favoriteDao) {
        this.favoriteDao = favoriteDao;
    }
    public FavoriteBiz() {
        super();
        System.out.println("FavoriteBiz的构造方法");
    }
}

beans.xml是这样的:

<bean id="favoriteBiz" class="com.yc.bean.FavoriteBiz" depends-on="favoriteDao,tagDao">
        <property name="favoriteDao" ref="favoriteDao" />
        <property name="tagDao" ref="tagDao" />
</bean> 
<bean id="tagDao" class="com.yc.bean.TagDao" />
<bean id="favoriteDao" class="com.yc.bean.FavoriteDao" />

运行结果当然是这三个类的构造方法都被调用了…….

好了写到这里只写了一些很基础的东西。。。。
可能还会有错。。。。
不要骂我。。发现了请及时告诉我我好改。。。
蟹蟹。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值