目录
通过注解完成java对象的创建和属性赋值
基于注解的di, 通过注解完成java对象的创建和属性赋值
使用注解步骤
1. 加入maven的依赖, spring-context, 在你加入spring-context的同时, 间接的加入了spring-aop的依赖
使用注解必须加入spring-aop依赖
<!-- Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
2. 在类中加入spring的注解(多个功能不同的注解)
3. 在spring的配置文件中加入一个组件扫描器的标签, 来说明注解在你的项目中的位置
在配置文件中加入下面语句
<context:component-scan base-package="org.example.ba01" />
<!--
声明组件扫描器(component-scan)
组件 : 指java对象
base-package : 在那个包中寻找
component-scan工作方式 : spring会遍历扫描base-package指定的包和其子包中的所有类
找到注解, 按照注解的功能创建对象或者给属性赋值
当加入了component-scan时, 配置文件会发生变化
1. 加入一个新的约束文件spring-context.xsd
2. 给这个新的约束文件起一个命名空间的名称
-->
主要注解
创建对象注解: 4个
1. @Component
例如:
@Component(value = "myStudent")
public class Student {
...
}
@Component: 是创建对象的, 等同于<bean>的功能
属性value就是创建出对象的名称, 也就是bean的id
value的值是唯一的, 创建的对象在整个spring容器中的就一个
注解位置 : 在某个类的上面
@Component(value = "myStudent") 等同于
<bean id="myStudent" class="org.example.ba01.Student" />
可以在spring容器中根据applicationContext.getBean("myStudent")取出
变形写法
@Component("myStudent") // 省略value(最常用)
@Component // 默认value为类名首字母小写, 比如Student之前加, value默认为student
在spring中和 @Component 功能一致, 创建对象的注解还有
2. @Respotory
用在持久层类的上面, 放在dao的实现类上面
表示创建dao对象, dao对象是访问数据库的
3. @service
用在业务层类的上面, 放在service的实现类上面
创建service对象, service对象是可以做业务处理的
4. @Controller
用在控制器上面, 放在控制器(处理器)类的上面, 创建控制器对象的
控制器对象, 能够接受用户提交的参数, 显示的请求处理的结果
以上三个注解的使用语法和 @Component 一样, 都可以创建对象
但是三个注解还有别的功能
@Respotory, @service, @Controller这是三个注解是给项目对象分层的
那什么时候用 @Component ? 不是上面三个类型就用
5. @Value
功能 : 简单类型的属性赋值
属性 : value = String类型, 表示简单类型的属性值
位置 : 1. 在属性定义的上面, 无序set方法, 推荐使用
2. 在set方法的上面
位置1实例:在属性定义的上面可以不写set方法也可以更新属性值
@Component("myStudent")
public class Student {
// 标准写法
@Value(value = "张飞")
private String name;
// 简略写法
@Value("29")
private Integer age;
public Student() {
System.out.println("无参构造执行");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
位置2实例:放在set方法上, 这种位置不常用
@Component("myStudent")
public class Student {
private String name;
private Integer age;
public Student() {
System.out.println("无参构造执行");
}
@Value("张飞")
public void setName(String name) {
System.out.println("name的set方法");
this.name = name;
}
@Value("30")
public void setAge(Integer age) {
System.out.println("age的set方法");
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
6. @Autowired
@Autowired : 引用类型的赋值
是由spring框架提供的注解, 使用的是自动注入原理, 支持byName, byType
默认使用的是byType自动注入
位置 : 1. 在属性定义的上面, 无需set方法, 推荐使用
2. 在set方法的上
默认状态下byType的代码例子:
Studen.java如下:
@Component("myStudent")
public class Student {
@Value("张飞")
private String name;
@Value("29")
private Integer age;
// 默认使用byType, 因为在School.java中
// 通过注解的方式构造了同源对象, 所以这里会直接注入
// 这里需要注意, School.java中是通过注解创造的同源对象的
// 如果使用配置文件创建这里也是可以自动注入的
// 也就是说, 只要spring容器中有且只有一个同源对象, 就可以在这里自动注入
@Autowired
private School school;
public Student() {
System.out.println("无参构造执行");
}
public void setName(String name) {
System.out.println("name的set方法");
this.name = name;
}
public void setAge(Integer age) {
System.out.println("age的set方法");
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
School.java如下
@Component("mySchool")
public class School {
@Value("北京大学")
private String name;
@Value("北京")
private String address;
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
使用byName的方式
如果使用byName方式, 需要做的是
1. 在属性上面加 @Autowire
2. 在属性上面加 @Qualifier(value="bean的id") : 表示用指定名称的bean完成赋值
3. 这两个注解没有先后顺序
例如:上面的代码Student类中改变如下
@Autowired
@Qualifier(value = "mySchool")
private School school;
@Autowire的required属性, 不指定这个属性的情况下, 默认为true
required=true : 表示引用类型赋值失败时, 程序会终止执行, 直接报错
required=false : 表示引用类型赋值失败时, 程序照常执行, 但是赋值失败的引用类型为null
开发中常用为true(默认不写), 因为这样可以尽早的暴露程序的错误, 方便修改
例子:
@Autowired(required = true)
@Qualifier(value = "mySchool-1")
private School school;
在spring容器中只有mySchool, 此时程序报错
@Autowired(required = false)
@Qualifier(value = "mySchool-1")
private School school;
此时打印:Student{name='张飞', age=29, school=null}
7. @Resource
@Resource
上面的注解都是由spring提供
@Resource是由JDK提供的(6以上), 功能是引用类型的自动注入,
默认是按照先byName, 如果byName失败, 再使用byType方式
但是也可以设置只使用byName或只是有byType方式
spring提供了对这个注解的支持
位置 : 1. 在属性定义的上方, 无需set方法, 推荐使用
2. 在set上方
使用byName
语法为 :
@Resource(name = "mySchool")
private School school;
扫描多个包的方式
第一种 : 多次使用组件扫描器
第二种 : 使用分隔符(,或者;)分隔多个包名
第三种 : 多个包如果都在一个父包下, 指定父包即可
<!--第一种-->
<context:component-scan base-package="org.example.ba01" />
<context:component-scan base-package="org.example.ba02" />
<!--第二种-->
<context:component-scan base-package="org.example.ba01;org.example.ba02" />
<!--第三种-->
<context:component-scan base-package="org.example" />