Spring应用注解配置实现IOC

一、组件自动扫描

可以按指定的包路径,将包下所有组件扫描,如果发现组件类定义前有以下标记,就会将组件扫描到容器。

@Component 其他组件

@Controller  控制层组件

@Service  业务层组件  XXXService

@Repository  数据访问层组件 XXXDao

@Named (不是Spring中定义的,需要引入第三方标准包)

组件自动扫描需要我们手动开启,开启方式即在applicationContext.xml中添加以下配置:

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

例如:

<?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"
    xmlns:util="http://www.springframework.org/schema/util"
    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-4.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-4.0.xsd" >
    
    <!-- 开启组件扫描 -->
    <context:component-scan base-package="com.zlc.test"/>
</beans>

base-package属性说明:例如其值为com.zlc.test,即指定spring框架将对com.zlc.test包下以及子包下所有组件进行扫描。

这样我们就可以在该包路径下写相关的组件了,Spring框架将对其进行自动扫描:例如:

package com.zlc.test;

import org.springframework.stereotype.Component;

@Component//扫描ExampleBean组件,默认id=exampleBean
public class ExampleBean {
    
    public void execute() {
        System.out.println("执行了方法");
    }
}

如果我们不想使用默认的id名,我们也可以这样为其指定特定的id名:

@Component("example")//指定id=example
public class ExampleBean {
    
    public void execute() {
        System.out.println("执行了方法");
    }
}

我们还可以像在xml文件中配置一样,指定该组件的某些属性,例如:scope, init-method, destroy-method, lazy-init等

例如:

//等价于指定<bean id="example">
@Component("example")
//等价于指定<bean scope="prototype">
@Scope("prototype")
//等价于指定<bean lazy-init="true">
@Lazy(true)
public class ExampleBean {
    
    //等价于<bean init-method="init">
    @PostConstruct
    public void init() {
        System.out.println("初始化。。。");
    }
    
    //等价于<bean destroy-method="destroy">
    @PreDestroy
    public void destroy() {
        System.out.println("释放资源。。。");
    }
        
    public void execute() {
        System.out.println("执行了方法");
    }
}

二、注解方式实现注入

(1)使用@Resource注解进行注入,注解可以加在需要注入的属性上,也可以加在相应的setter方法上

例如:

@Component("s")
public class Student {
    //定义在变量上
    @Resource
    private Computer c;
    
    private Phone p;
    
    public void setC(Computer c) {
        this.c = c;
    }
    //定义在setter方法上
    @Resource
    public void setP(Phone p) {
        this.p = p;
    }
    
    public void show() {
        System.out.println("学生信息。。。");
        c.show();
        p.show();
    }
}

(2)使用@Autowired注解进行注入,注解可以加在需要注入的属性上,也可以加在相应的setter方法上

例如:

@Component("s")
public class Student {
    //定义在变量上
    @Autowired
    private Computer c;
    
    private Phone p;
    
    public void setC(Computer c) {
        this.c = c;
    }
    //定义在setter方法上
    @Autowired
    public void setP(Phone p) {
        this.p = p;
    }
    
    public void show() {
        System.out.println("学生信息。。。");
        c.show();
        p.show();
    }
}

注意:我们甚至还可以去掉这两个属性的setter方法,直接在属性上添加@Resource或者@Autowired注解,这样也是可以完成注入的

例如:

@Component("s")
public class Student {
    //定义在变量上
    @Autowired
    private Computer c;
    @Autowired
    private Phone p;
    
    public void show() {
        System.out.println("学生信息。。。");
        c.show();
        p.show();
    }
}

使用@Resourse或者@Autowired注解方式进行注入的时候,默认使用的是"byName"的匹配方法,使用的是默认名称(即需要注入的属性的名称),如果"byName"的匹配方法找不到相应的组件,则会使用"byType"的匹配方法寻找相应的组件。

特别的,我们可以指定特定名称的组件进行注入

例如:

    @Autowired
    @Qualifier("p1")//指定id名称为p1的组件进行注入
    private Phone p;

或者

    @Resource(name="p1")//指定id名称为p1的组件进行注入
    private Phone p;

一般使用时,@Resource注解和@Autowired注解可以看做是等价的。

但是这两者在某些情况下仍是有些细微的差别的:

a、当注解直接声明在属性变量上,两者无差别,但是声明在setter方法上,默认使用 "byName"方法去匹配将要注入的bean时,选择的Name不一样。

如:

 //@Resource是以setXXX方法名中XXX首字母小写后的名字去进行匹配的,即标红的单词首字母小写
    public void setP(Phone p) {
        this.p = p;
    }

但是:

 //@Autowired是以setXXX方法中参数名去匹配的,即标红的单词
    public void setP(Phone p) {
        this.p = p;
    }

b、@Autowired注解可用于构造器上,进行构造注入,但是@Resource不行,例如可以这样使用:

    @Autowired
    public Student(Computer c,Phone p) {
        this.c = c;
        this.p = p;
    }

但是这样使用则不行:

    @Resource(这样使用错误,将会提示编译错误)
    public Student(Computer c,Phone p) {
        this.c = c;
        this.p = p;
    }

 (3)使用Spring表达式注入

    @Value("spring表达式")
    private Phone p;

 

   @Value("#{user.name}")
    private String name;

 

(4)int或者String等基本值的注入,也可以使用@Value注解,如:

    @Value("小明")
    private String name;

这样就可以为name属性注入值"小明"了

posted @ 2018-08-02 18:56  梦里下起了雪  阅读(444)  评论(0编辑  收藏  举报