咱们这里有个类 Personhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 对象,咱们要进行以下配置:java
applicationContext.xml 配置:web
1
|
<bean id=
"person"
class
=
"com.ys.annotation.Person"
></bean>
|
若是使用注解呢?spring
第一步:在 applicationContext.xml 中引入命名空间app
这里咱们简单讲解一下这里引入的命名空间,简单来讲就是用来约束xml文件格式的。第一个 xmlns:context ,这表示标签格式应该是 <context:标签名>ide
第二步:在 applicationContext.xml 文件中引入注解扫描器函数
1
2
|
<!-- 组件扫描,扫描含有注解的类 -->
<context:component-scan base-
package
=
"com.ys.annotation"
></context:component-scan>
|
base-package:表示含有注解类的包名测试
若是扫描多个包,则上面的代码书写多行,改变 base-package 里面的内容便可!ui
第三步:在 Person 类中添加注解@Componentthis
第四步:测试
1
2
3
4
5
6
7
8
9
10
|
@Test
public
void
testAnnotation(){
//一、启动 spring 容器
//二、从 spring 容器中取出数据
//三、经过对象调用方法
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") 这样写。
此外:下面三个注解是 @Component 注解的衍生注解,功能同样
1
2
3
|
@Repository
:dao层
@Service
:service层
@Controller
:web层
|
@Resource 注解,它能够对类成员变量、方法及构造函数进行标注,完成自动装配的工做。 经过 @Resource 的使用来消除 set ,get方法。
首先建立一个 学生类 Student.java
而后在 Person 类中添加一个属性 Student
那么咱们如何获取 Person 对象,并调用 showStudent()方法呢?这个问题简化就是如何给属性 Student 实例化,也就是依赖注入
不使用注解:
1
2
3
4
|
<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进行匹配,匹配成功,则赋值,不成功则报错
功能和注解 @Resource 同样,能够对类成员变量、方法及构造函数进行标注,完成自动装配的工做。只不过注解@Resource 是按照名称来进行装配,而@Autowired 则是按照类型来进行装配。
第一步:建立接口 PersonDao
1
2
3
4
5
6
7
|
package
com.ys.autowired;
public
interface
PersonDao {
public
void
savePerson();
}
|
第二步:建立一个接口实现类 PersonDaoImplOne
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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