Spring IoC介绍

在前一篇文章中,我们讲了java web项目搭建,现在看下spring ioc在java中的运用,开发工具为Intellij Idea。

1、简介
IoC(Inversion of Control)通常称为控制反转,是Spring框架的核心。即通过Spring容器控制对象之间的依赖关系,而不是对象自己通过new的方式去创建依赖的对象,相对于主动去创建对象,这种失去对对象的控制便叫做控制反转,控制反转用另一种角度描述或者更好的一种理解方式来讲,便是DI(Dependency Injection)依赖注入,对象只需关注业务逻辑本身即可,而不需关注依赖的对象从哪里来,交给容器注入即可,从而降低程序之间的耦合度。

2、用法
依赖注入在spring中有两种配置方式,一是xml配置Bean的方式,二是自动装配检测Bean。

2.1 xml配置Bean
2.1.1 创建Spring配置
我们在web层,web-inf/dispatcher-servlet.xml中注入service层的实现类,加入如下代码:

2.1.2 在web层controller下调用
我们在类里声明对象,并在方法里调用,这里我们的service层接口类可以声明为私有属性,程序可通过@Inject自动搜索xml中的bean配置,注入依赖。

//   声明对象 DemoUserServiceImpl实现DemoUserService接口
@Inject  
private DemoUserService demoUserService;

@RequestMapping(value="/index", method = {RequestMethod.GET})
public ModelAndView index(){
    DemoUserEntity demoUser=demoUserService.GetDemoUser(1);
    modelAndView.addObject("demoUser", demoUser);
    modelAndView.setViewName("home");
    return modelAndView;
}

我们在属性前加了@Inject,这里依赖javax.inject.Inject包 ,在模块pom里加入如下依赖即可

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
</dependency>

2.1.3 属性的依赖注入
如果我们想在service层依赖注入调用dao层对象操作数据库,则跟service层类似,我们在web层的web-inf/dispatcher-servlet.xml注入dao层的实现,加入如下代码:

<bean id="demoUserDao" class="com.ganji.demo.dao.gcrm.hibernate.DemoUserDaoHibernate"></bean>
<bean id="demoUserService" class="com.ganji.demo.service.user.DemoUserServiceImpl" autowire="byType">
    <property name="demoUserDao" ref="demoUserDao"></property>
</bean>

ref指像bean的实现类,如果是值类型或String类型可以用value指定,设定值即可,如value=5。
在service层,我们可以在DemoUserServiceImpl层里声明demoUserDao私有属性,并公开属性set方法,然后调用。

//声明属性
private DemoUserDao demoUserDao;

//通过属性的set方法,注入对象
public void setDemoUserDao(DemoUserDao demoUserDao)
{
    this.demoUserDao=demoUserDao;
}

public DemoUserEntity GetDemoUser(int id) {
    return demoUserDao.getDemoUser(id);
}

2.1.4 构造器注入
构造器注入类似于属性注入,在xml中用constructor-arg来指定,这里我们在web层的web-inf/dispatcher-servlet.xml配置如下:

<bean id="demoUserService" class="com.ganji.demo.service.user.DemoUserServiceImpl" autowire="byType">
    <constructor-arg name="demoUserDao" ref="demoUserDao"></constructor-arg>
    <constructor-arg name="userName" value="张三"></constructor-arg>
</bean>

在service层,创建构造函数

private DemoUserDao demoUserDao;
private String userName;

public DemoUserServiceImpl(DemoUserDao demoUserDao,String userName)
{
   this.demoUserDao=demoUserDao;
   this.userName=userName;
}

//在方法里既可以调用了,如下代码

 public DemoUserEntity GetDemoUser(int id) {
    System.out.println("execute service getdemouser "+userName);
    return demoUserDao.getDemoUser(id);
}

2.1.5 小结
如果我们不想在xml中配置属性注入或者构造器注入,我们可以在声明的属性上,添加@Inject注解,类似2.1.2中demoUserService的实现,这样Spring框架会自动搜索bean对应的实现类,可以在bean处设置根据名称或类型,即autowire=”byType” or autowire=”byName”,也可以全局设置,即在根目录beans下面声明default-autowire=”byName”,具体如下。

<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"
   default-autowire="byName"

2.2 自动装配检测Bean
如果每个实现类都要配置bean元素的话,项目如果很大的情况下,太多的bean,xml文件的bean管理配置就成了一个问题,很庆幸的事,spring提供了自动装配检测bean注入依赖的功能。

2.2.1 自动检测标注bean
我们依赖查找使用注解所标注的类,这些注解如下:

@Component --通用的构造性注解,标识该类为Spring组件
@Controller --标识将该类定义为Spring MVC Controller 这里我们用在web层
@Service --标识将该类定义为服务,这里我们用在Service层
@Repository --标识将该类定义为数据仓库,这里我们用在Dao层

具体用法如下示例

web层调用
@Controller
public class HelloWorldController {}

service层调用
@Service
public class DemoUserServiceImpl implements DemoUserService {}

dao层调用
@Repository
public class DemoUserDaoHibernate implements DemoUserDao {}

注解后,我们需要在web层的web-inf/dispatcher-servlet.xml配置组件扫描,分别扫描web、service。dao层,具体如下:

<!-- 开启controller注解支持 -->
<!-- use-default-filters="false" 只扫描指定的注解 -->
<context:component-scan base-package="com.ganji.demo.web.controller" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!--服务层自动依赖注入-->
<context:component-scan base-package="com.ganji.demo.service">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>

<!--Dao层依赖注入-->
<context:component-scan base-package="com.ganji.demo.dao">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>

同时,我们需要在xml命名空间里加入context支持,xmlns:context="http://www.springframework.org/schema/context"和相应的xsi具体如下:

<?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.xsd"
        default-autowire="byName"
    >

2.2.2 使用自动注入的bean
上一步配置好后,我们只需要声明调用对象的属性即可,如下:

//web层如下
//声明对象 DemoUserServiceImpl实现DemoUserService接口
@Inject  
private DemoUserService demoUserService;

@RequestMapping(value="/index", method = {RequestMethod.GET})
public ModelAndView index(){
    DemoUserEntity demoUser=demoUserService.GetDemoUser(1);
    modelAndView.addObject("demoUser", demoUser);
    modelAndView.setViewName("home");
    return modelAndView;
}

//service层如下
@Inject
private DemoUserDao demoUserDao;

public DemoUserEntity GetDemoUser(int id) {
    return demoUserDao.getDemoUser(id);
}

2.2.3 总结
按2.2.1和2.2.2配置操作后,即可实现自动检查依赖注入bean,不用在xml中配置繁琐的bean元素,由框架通过反射自动寻找对象实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值