Spring的IOC(控制反转)的XML配置和注解开发(一)

一、IOC(控制反转)

所谓的控制反转就是将对象的创建权交给Spring。对象不在由我们自己手动实例化,而是通过Spring的配置进行实例化。那么为什么要进行控制反转,是为了程序能够更好的解耦和,倘若,由于一些需求,原本底层是使用jdbc实现Dao接口的,此时,如果要求使用hibernate实现Dao接口,那么,我是不是要将项目中所有实例化jdbc的类,全部改成实例化hibernate。此时,我是不是要一个个打开项目中的文件将JdbcDaoImpl修改为HibernateDaoImpl,这样的项目耦合是不是很大,所以使用Spring就可以帮我们很好的解决这个问题。只需要修改配置文件就可以达到目的。

IOC的底层实现原理是“工厂模式”+“反射”+“配置文件”。在Spring中注入一个类,在applicationContext.xml(Spring中的核心配置)对它进行配置。

 <bean id="productDao" class="demo3.ProductDaoImpl"></bean>

id可以任意取值,但是在applicationContext中要唯一,class表示注入的类,即类的全路径

通过配置文件中的类,我们便可以找到实现类。即配置文件+反射。在通过工厂模式便可以实现管理Spring中的注入类。

 

二、IOC的实现

(1)使用xml方式

新建applicationContext.xml文件(命名可以为applicationContext官方推荐,当然也可以不是,但在加载配置文件的时候要注意)

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

...............................................

</beans>

控制反转就是,在applicationContext中配置bean

bean中主要有三个重要的参数,id值,class值,以及scope值。当然还有init-method和destroy-method(了解即可)的配置

id值:applicationContext中的唯一标识,id的作用不言而喻,找到实现类

class值:实现类的全路径,通过id找到该实现类

scope值:作用范围的意思

scope一共有5个参数

singleton:(默认)spring采用单例模式创建对象(常用)

prototype:spring采用多例模式创建对象(常用,在整合struts2时,要记住改为多例模式)

request:spring创建这个对象后将它存入到request范围中

session:spring创建这个对象后将它存入到session范围中

globalsession:在prolet环境下使用,所谓的prolet就是指一个系统用许多子系统,譬如百度搜索,但我登录百度账号后,我的百度云可以使用我的个人信息,我的百度知道可以使用我的个人信息。这样就是prolet环境。spring创建这个对象后将它存入到prolet环境中。

xml配置

   <bean id="userDao" class="spring.dao.impl.UserDaoImpl" 
        scope="singleton" init-method="save" destroy-method="delete"></bean>

UserDaoImpl类

package spring.dao.impl;

import spring.dao.UserDao;

public class UserDaoImpl implements UserDao{

    @Override
    public void save() {
        System.out.println("UserDaoImpl中的save方法执行了......");
    }

    @Override
    public void update() {
        System.out.println("UserDaoImpl中的update方法执行了......");
    }

    @Override
    public void delete() {
        System.out.println("UserDaoImpl中的delete方法执行了......");
    }

    @Override
    public void find() {
        System.out.println("UserDaoImpl中的find方法执行了......");
    }

}

测试 

@Test
    public void test01(){

//申明工厂类,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

//通过ID值获取实体类
        UserDao bean = (UserDao) applicationContext.getBean("userDao");

//执行update方法
        bean.update();
    }

结果

UserDaoImpl中的save方法执行了......
UserDaoImpl中的update方法执行了......
 

 因为,我在配置文件中设置了初始化方法init-method,所以先执行save方法。至于为什么没有执行destroy-method是因为我没有关闭

public void test01(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao bean = (UserDao) applicationContext.getBean("userDao");
        bean.update();
        applicationContext.close();
    }

这样就会执行destroy-method方法。 

(2)使用注解方式

使用注解进行控制反转,首先需要在applicationContext中开启包扫描。意思是加载配置文件的时候后,让Spring去扫描含有注解的类

xml的配置

<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.xsd"> 
    
  <context:component-scan base-package="spring.dao"/>
</beans>

 

对于xml的配置,首先使用包扫描,需要引入context约束

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"

开启包扫描

  <context:component-scan base-package="spring.dao"/>

这样就可以对spring.dao下的所有类进行扫描

设置Repository表示Dao层的注解

Service表示业务层的注解

Controller表示控制层的注解

Scope表示作用范围

@Repository("userDao")
@Scope("prototype")
public class UserDaoImpl implements UserDao{

    @Override
    public void save() {
        System.out.println("UserDaoImpl中的save方法执行了......");
    }

    @Override
    public void update() {
        System.out.println("UserDaoImpl中的update方法执行了......");
    }

    @Override
    public void delete() {
        System.out.println("UserDaoImpl中的delete方法执行了......");
    }

    @Override
    public void find() {
        System.out.println("UserDaoImpl中的find方法执行了......");
    }

}

测试

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
        UserDao bean = (UserDao) applicationContext.getBean("userDao");
        bean.update();
        System.out.println(bean);
        System.out.println("==============================");
        ApplicationContext applicationContext2 = new ClassPathXmlApplicationContext("applicationContext2.xml");
        UserDao bean2 = (UserDao) applicationContext.getBean("userDao");
        bean2.update();
        System.out.println(bean2);

结果

UserDaoImpl中的update方法执行了......
spring.dao.impl.UserDaoImpl@4034c28c
==============================
UserDaoImpl中的update方法执行了......
spring.dao.impl.UserDaoImpl@5e4c8041
 

从结果中可以看出bean是不等于bean2的,因为我设置的是多例模式。

 

关于属性注入的部分将在下面慢慢讲述 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值