Spring详解(四)------注解配置IOC、DI

  Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的。

  前面讲解 IOC 和 DI 都是通过 xml 文件来进行配置的,我们发现 xml 配置还是比较麻烦的,那么如何简化配置呢?答案就是使用注解!

  PS:本篇博客源码下载链接:http://pan.baidu.com/s/1geBMPrX 密码:z7ku

1、注解 @Component

  我们这里有个类 Person

package com.ys.annotation;

public class Person {
	private int pid;
	private String pname;
	private String psex;
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getPsex() {
		return psex;
	}
	public void setPsex(String psex) {
		this.psex = psex;
	}
}

  如果我们不使用注解,通过前面讲解的,要想让 Spring 容器帮我们产生 Person 对象,我们要进行如下配置:

  applicationContext.xml 配置:

<bean id="person" class="com.ys.annotation.Person"></bean>

  如果使用注解呢?

第一步:在 applicationContext.xml 中引入命名空间

   这里我们简单讲解一下这里引入的命名空间,简单来说就是用来约束xml文件格式的。第一个 xmlns:context ,这表示标签格式应该是 <context:标签名>

第二步:在 applicationContext.xml 文件中引入注解扫描器

<!-- 组件扫描,扫描含有注解的类 -->
	<context:component-scan base-package="com.ys.annotation"></context:component-scan>

  base-package:表示含有注解类的包名

     如果扫描多个包,则上面的代码书写多行,改变 base-package 里面的内容即可!

第三步:在 Person 类中添加注解@Component

第四步:测试

@Test
	public void testAnnotation(){
		//1、启动 spring 容器
		//2、从 spring 容器中取出数据
		//3、通过对象调用方法
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) context.getBean("person");
		System.out.println(person.getPname());
	}

   如果看完上面的注解配置,你一脸懵逼,那没关系,我们下面来详细讲解。

@Component

  如果一个类上加了@Component注解,就会进行如下的法则               如果其value属性的值为""                     @Component                     public class Person {}                       等价于                     <bean id="person" class="..Person">              如果其value属性的值不为""                     @Component("p")                     public class Person {}                      等价于                    <bean id="p" class="..Person">

  那么这就很好理解测试程序中,我们直接  context.getBean("person") 这样写。

2、@Repository    @Service   @Controller

  此外:下面三个注解是 @Component 注解的衍生注解,功能一样

@Repository :dao层
@Service:service层
@Controller:web层

3、注解 @Resource

  @Resource 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Resource 的使用来消除 set ,get方法。

  首先创建一个 学生类 Student.java

  然后在 Person 类中添加一个属性 Student

  那么我们如何获取 Person 对象,并调用 showStudent()方法呢?这个问题简化就是如何给属性 Student 实例化,也就是依赖注入

不使用注解:

<property name="students">
	<ref bean="student"/>
</property>
<bean id="student" class="com.ys.annotation_di.Student"></bean>

使用注解:

  @Resource注解以后,判断该注解name的属性是否为""(name没有写)

    ①、如果没有写name属性,则会让属性的名称的值和spring配置文件bean中ID的值做匹配(如果没有进行配置,也和注解@Component进行匹配),如果匹配成功则赋值,如果匹配不成功,则会按照spring配置文件class类型进行匹配,如果匹配不成功,则报错

    ②、如果有name属性,则会按照name属性的值和spring的bean中ID进行匹配,匹配成功,则赋值,不成功则报错

4、注解 @Autowired

  功能和注解 @Resource 一样,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。只不过注解@Resource 是按照名称来进行装配,而@Autowired 则是按照类型来进行装配。

  第一步:创建接口 PersonDao

package com.ys.autowired;

public interface PersonDao {
	
	public void savePerson();

}

  第二步:创建一个接口实现类 PersonDaoImplOne

package com.ys.autowired;

import org.springframework.stereotype.Component;

@Component("personDaoImplOne")
public class PersonDaoImplOne implements PersonDao{

	@Override
	public void savePerson() {
		System.out.println("save Person One");
		
	}

}

  第三步:创建PersonService

package com.ys.autowired;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("personService")
public class PersonService{
	@Autowired
	private PersonDao personDao;
	
	public void savePerson() {
		this.personDao.savePerson();
	}

}

  注意:这里我们在 private PesronDao personDao 上面添加了注解 @Autowired,它首先会根据类型去匹配,PersonDao 是一个接口,它的实现类是 PesronDaoImpOne,那么这里的意思就是:

  PersonDao personDao = new PersonDaoImpOne();

  那么问题来了,如果 PersonDao 的实现类有多个呢?我们创建第一个实现类 PersonDaoImpTwo

package com.ys.autowired;

import org.springframework.stereotype.Component;

@Component("personDaoImplTwo")
public class PersonDaoImplTwo implements PersonDao{

	@Override
	public void savePerson() {
		System.out.println("save Person Two");
		
	}

}

  如果还是向上面那样写,那么测试就会报错。怎么解决呢?

第一种方法:更改名称

第二种方法:@Autowired 和 @Qualifier("名称") 配合使用

  在使用@Autowired时,首先在容器中查询对应类型的bean

    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

    如果查询的结果不止一个,那么@Autowired会根据名称来查找。

    如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏静默虚空的博客

[spring]03_装配Bean

3.1 JavaBean 3.1.1 JavaBean 是什么 JavaBean 是一种JAVA语言写成的可重用组件。 为写成JavaBean,类必须是具体的和...

1809
来自专栏xdecode

Spring之IOC

IOC 控制反转, 将由程序直接操控的对象调用权交给容器, 通过容器来实现对象的装配和管理. 容器即applicationContext.xml 第一个spri...

1727
来自专栏java 成神之路

spring 循环依赖注入

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

【Spring实战】—— 2 构造注入

本文讲解了构造注入以及spring的基本使用方式,通过一个杂技演员的例子,讲述了依赖注入属性或者对象的使用方法。   如果想要使用spring来实现依赖注...

1938
来自专栏Java Edge

SpringMVC之Controller查找(Spring4.0.3/Spring5.0.4源码进化对比)0 摘要1 SpringMVC请求流程2 SpringMVC初始化过程总结

3466
来自专栏每日一篇技术文章

Swift3.0 - 真的很简单

中文翻译文档 https://github.com/numbbbbb/the-swift-programming-language-in-chinese

891
来自专栏javathings

SpringBoot 中异常处理

SpringBoot 中异常处理非常简单,通过@ControllerAdvice 和@ExceptionHandler 注解,可以实现自定义的统一异常处理模块。

1014
来自专栏Java帮帮-微信公众号-技术文章全总结

Spring-IOC(2)

scope <!--Spring使用scope标签来制定bean的作用域(默认为Singleton)--> <bean id="singletonBean" c...

32810
来自专栏Java学习之路

02 Spring框架 简单配置和三种bean的创建方式

整理了一下之前学习Spring框架时候的一点笔记。如有错误欢迎指正,不喜勿喷。 上一节学习了如何搭建SpringIOC的环境,下一步我们就来讨论一下如何利...

3115
来自专栏Google Dart

Spring Task 组件使用二 原

571

扫码关注云+社区