IOC注解配置

Spring中IOC功能的使用有两种方式,依赖注入和依赖查找,依赖注入已经介绍,注解方式将Bean组件定义到Spring容器,并完成Bean对象的关系注入,下面学习通过注解配置方式实现依赖查找。

注解简介:
注解技术是在jdk5.0版本出现的,注解是一种符号标记,可以写在类定义前,方法定义前,成员变量定义前。
格式是:@标记名,常见的有@Test,@Service,@Override等标记。
现在注解配置在主流的框架如struts,hibernate,spring中得到广泛的应用,原因是注解方式直观方便,而且很多元素都不需要在Spring配置文件中定义了,这样大大简化了xml配置内容。
注解名在框架底层代码定义,通过反射技术,读取注解符号运行底层代码,实现相应的功能。

由于依赖注入和依赖注解注入是实现IOC功能的两种方式,通过依赖注入实现的Demo修改成注解注入实现方式,来了解这两种方式的优劣异同。
依赖注入的实现方式可以参考:SpingIOC依赖注入
两种方式本质一样,都是实现项目组件之间的解耦,组件之间的关系采用IOC注入的方式。
IOC依赖注入方式的步骤是:
1.将各组件声明定义到Spring容器中,由Spring容器来创建生成声明组件的对象实例。
2.组件之间的关系使用设值注入( ref=”要注入的Bean的ID”)或者构造注入在配置文件中添加相应的属性赋值。
这里写图片描述

需要把所有用到的组件全部使用bean配置的方式写入到配置文件中,如果组件过多,那配置起来也非常费事麻烦,已经知道IOC注解配置可以简化xml文件的配置,那么通过注解配置的方法如何实现这个过程呢?

组件自动扫描技术了解一下:
在XML中开启组件扫描技术,指定一个包路径,Spring框架就会自动扫描包中的组件,如果在类定义之前有相应的指定标记,就会将类组件扫描到Spring容器中,相当于在xml定义了< bean id=”组件id” class=”类型”>

通过这种自动扫描技术,极大简化了程序中大量组件的定义。
组件定义的指定标记有这样几种:
@Controller ———–控制层
@Service ————业务层
@Repository ————-数据操作层(Dao)
@Component ———–其他
更高级的版本支持下面这种方式,不过需要导入额外的包。
@Named
当前很多项目都是采用分层管理的方式,常见的有MVC框架思想,为了区分各层次就采用不同的关键字,在简单的Demo中,就可以随意选择了。

先在配置文件中用组件扫描技术代替bean定义声明。

<?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: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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <!--依赖注入方式-->
        <!--把类对象都交给Spring管理-->
        <!--Computer-->
        <!--<bean id="cpid" class="com.hnust.simpleclass.Compupter" >
                &lt;!&ndash;设置接口变量值(设值注入方式)&ndash;&gt;
                <property name="usb" ref="upid"></property>
                &lt;!&ndash;设置接口变量值(构造注入方式)&ndash;&gt;
                &lt;!&ndash;
                <constructor-arg ref="upid"></constructor-arg>
                &ndash;&gt;
        </bean>
        &lt;!&ndash;U盘&ndash;&gt;
        <bean id="upid" class="com.hnust.simpleclass.UDisk"></bean>
        &lt;!&ndash;移动硬盘&ndash;&gt;
        <bean id="movedid" class="com.hnust.simpleclass.MoveDisk"></bean>-->
        <!--依赖查找方式-->
        <!--开启组件扫描-->
        <context:component-scan base-package="com.hnust"/>
</beans>

(在注释xml中内容时,如果要注释的内容已经包含注释符号,那么再添加注释会出错,目前尚未找到好办法,只能选中要注释的内容,选择快捷键“shift+ctr+/”)。

在所需要使用的组件类定义前添加上述标记(以计算机使用U盘为例):
计算机类:

package com.hnust.simpleclass;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class Computer {
    //定义USB接口变量
    @Resource
   private USB usb;
    //设值注入方式
   // public void setUsb(USB usb) {
     //   this.usb = usb;
  //  }
    /*
    //构造注入方式
    public Computer(USB usb){
        this.usb= usb;
    }
    */
    public void readData(){
        usb.useUSB();
        System.out.println("计算机读取数据....");
    }
}

U盘类:

package com.hnust.simpleclass;

import org.springframework.stereotype.Component;

@Component
public class UDisk implements USB {

    @Override
    public void useUSB() {
        System.out.println("U盘插入USB接口");
    }
}

在类名定义前加入了@Component标识,表示这两个类可以通过组件扫描技术由Spring容器创建实例。
那么如何表示计算机类和U盘类之间的关系呢??
可以在Computer类的成员变量usb定义之前加入@Resource标识,表示计算机类需要使用U盘类,此时U盘对象传入计算机,这样就建立起了组件之间的注入关系,当然也可以使用另外一个注入标记@Autowired。这两种标识还是有区别的,@Resource先按名称匹配注入,没有再按类型注入,@Autowired先按照类型注入,再按照名称。
两者都可以按照名称注入
1.@Resource(“名称”)

2.@Autowired
@Qualifier(“名称”)

写一个测试类测试注解配置是否成功:
TestIoCDI类代码

package com.hnust.iocdi;
import com.hnust.simpleclass.Computer;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestIoCDI {

   @Test
    public void test1(){
        ApplicationContext atc = new ClassPathXmlApplicationContext("spring-config.xml");
        Computer cp =atc.getBean("computer",Computer.class);
        cp.readData();
    }
}

运行一下:
这里写图片描述
通过注解配置的方式运行成功!

分析一下这行代码

Computer cp =atc.getBean("computer",Computer.class);

在注解配置中,并没有在配置文件中填写Bean配置相关的内容,那么这个Bean是怎么得到的呢?
在Computer类定义之前增加了注解标记@Component,通过注解扫描已经自动创建了Computer类型的Bean,那这个“computer”id是怎么回事呢?系统默认id名是类名的首字母小写,当然我们也可以指定id名,方式是@Component(“指定id名”),

为什么有些组件在标记时需要指定id名呢,因为有些组件有多个实例,一个类型可以new多个对象,在Spring默认的情况下,获取的Bean实例都是通过单例模式创建的,我们可以修改测试类代码验证一下。
TestIoCDI类

package com.hnust.iocdi;
import com.hnust.simpleclass.Computer;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestIoCDI {

   @Test
    public void test1(){
        ApplicationContext atc = new ClassPathXmlApplicationContext("spring-config.xml");
        Computer cp =atc.getBean("computer",Computer.class);
        Computer cp1=atc.getBean("computer",Computer.class);
        //cp.readData();
       System.out.println(cp==cp1);
    }
}

输出结果为:
这里写图片描述
得到的cp1和cp是同一个对象,因为默认是以单例组件类创建的,我们可以在Computer类的@Component标识之后加入@Scope(“prototype”)控制对象创建为非单例,这样就可以获取到多个实例对象了。
这里写图片描述
这里写图片描述

以上就完成了IOC注解配置基本使用,只是暂时了解注解注入的使用和注解的标记认识,有助于后续理解项目的代码,至于更深入的使用和更多标识的使用还需要更多的时间慢慢学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值