【SSH快速进阶】——Spring IOC容器注入的几种方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/52022311

IOC(Inversion of Control):控制反转,怎么理解这句话呢?看一个例子就明白了。

  一个操作用户的Dao层接口UserDao :

public interface UserDao {
    public void addUser(String username,String password);
}

  UserDao 的两个实现类(Oracle版本和MySql版本):

public class UserDao4OracleImpl implements UserDao{
    @Override
    public void addUser(String username, String password) {
        System.out.println("UserDao4Oracle实现添加用户");
    }
}
public class UserDao4MySqlImpl implements UserDao {
    @Override
    public void addUser(String username, String password) {
        System.out.println("UserDao4MySqlImpl实现添加用户");
    }
}

  在Service的实现类中调用UserDao接口时,需要手动new实现该接口的实现类:

public class UserManagerImpl implements UserManager{
    @Override
    public void addUser(String username, String password) {
        //由应用程序自己来负责服务(对象)定位
        UserDao userDao =new UserDao4MySqlImpl();
        userDao.addUser("DannyHoo", "123456");
    }
}

  在上面的代码看出来,在使用userDao接口时,需要在这里主动找mysql的实现类UserDao4MySqlImpl,而IOC的工作就是自动为我们实例化。

  控制反转的意思在这里就体现出来了,把原本由程序管理Bean的工作(实例化、各种依赖引用等)反交给IOC容器来做。

  利用IOC容器来为我们管理Bean的方式有多种:

1、构造方法注入


  在需要注入的Service实现类中添加userDao的引用,一个构造方法,参数为需要注入的userDao:

public class UserManagerImpl implements UserManager{
    //用构造方法构造UserDao,不依赖具体实现
    private UserDao userDao;
    //如果有多个依赖,构造方法可以配置多个参数
    public UserManagerImpl(UserDao userDao){
        this.userDao=userDao;
    }

    @Override
    public void addUser(String username, String password){
        userDao.addUser(username,password);
    }
}

  上面用构造方法构造UserDao,不依赖具体实现。

  在Spring配置文件中的配置如下

<bean id="userDao4MySql" class="com.danny.spring.dao.UserDao4MySqlImpl"></bean>

<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDao4OracleImpl"></bean>

<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
    <!-- 依赖查找,可以构造多个参数依赖,顺序随意 -->
    <constructor-arg ref="userDao4MySql"/>
</bean>  

2、Setter注入


  Setter注入就是用Setter方法代替了上面的构造方法,IOC容器利用Setter方法来给需要注入的引用赋值。这是最常用的方式。

  添加Setter 方法:

public class UserManagerImpl implements UserManager{
    private UserDao userDao;
    //setter注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void addUser(String username, String password) {
        userDao.addUser(username,password);
    }
}

  在Spring配置文件中的配置如下

<bean id="userDao4MySql" class="com.danny.spring.dao.UserDao4MySqlImpl"></bean>

<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDao4OracleImpl"></bean>

<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
    <property name="userDao" ref="userDao4MySql"/>
</bean> 

3、静态工厂注入


  当我们通过静态工厂来获取Dao的实例时,比如再添加一个UserDaoFactory

public class UserDaoFactory {
    //生产UserDao4MySqlImpl实例
    public static final UserDao4MySqlImpl getUserDao4MySqlImpl(){
        return new UserDao4MySqlImpl();
    }
    //生产UserDao4OracleImpl实例
    public static final UserDao4OracleImpl getUserDao4OracleImpl(){
        return new UserDao4OracleImpl();
    }
}

  UserManagerImpl中的代码还跟Setter注入的代码一样:

public class UserManagerImpl implements UserManager{
    private UserDao userDao;
    //setter注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void addUser(String username, String password) {
        userDao.addUser(username,password);
    }
}

  但是配置文件不一样:

<bean id="userDao4MySql" class="com.danny.spring.dao.UserDaoFactory" factory-method="getUserDao4MySqlImpl"/>

<bean id="userDao4Oracle" class="com.danny.spring.dao.UserDaoFactory" factory-method="getUserDao4OracleImpl"/>

<bean id="userManager" class="com.danny.spring.manager.UserManagerImpl">
    <property name="userDao" ref="userDao4MySql"/>
</bean> 

  上面配置文件中,userManager的注入的参数仍然是userDao,ref是userDao4MySql或userDao4Oracle,userDao4MySql和userDao4Oracle,他们的的class不再指向自己,而是指向生产他们的静态工厂,factory-method则是生产他们的方法。


【 转载请注明出处——胡玉洋《【SSH快速进阶】——Spring IOC容器注入的几种方式》】

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏何俊林

LeakCanary的原理,你知道么?

2612
来自专栏闵开慧

Mapreduce任务实现邮件监控

Mapreduce任务实现邮件监控     这里主要使用Java自带邮件类实现Mapreduce任务的监控,如果Mapreduce任务报错则发送报错邮件。Map...

3318
来自专栏wannshan(javaer,RPC)

dubbo监控机制之监控中心实现分析

这里的监控中心以dubbo-ops\dubbo-monitor-simple项目说 总的来说是监控中心启动一个sevlet容器,通过web页面向用户多维度的展...

1.2K6
来自专栏石奈子的Java之路

原 SpringBoot 2.0 系列00

1384
来自专栏岑玉海

Carbondata源码系列(一)文件生成过程

在滴滴的两年一直在加班,人也变懒了,就很少再写博客了,最近在进行Carbondata和hive集成方面的工作,于是乎需要对Carbondata进行深入的研究。 ...

5976
来自专栏魂祭心

原 结合源码分析 setTimeout /

3496
来自专栏xingoo, 一个梦想做发明家的程序员

【插件开发】—— 9 编辑器代码分块着色-高亮显示!

前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 5 SWT简单控件的使用与布局搭...

2746
来自专栏Android学习之路

Android中关于UUID的操作

6316
来自专栏菩提树下的杨过

velocity模板引擎学习(4)-在standalone的java application中使用velocity及velocity-tools

通常velocity是配合spring mvc之类的框架在web中使用,但velocity本身其实对运行环境没有过多的限制,在单独的java applicati...

2688
来自专栏分布式系统进阶

Librdkafka的操作处理队列

2492

扫码关注云+社区

领取腾讯云代金券