目录
IOC/DI 注解开发
环境准备
- 创建一个Maven项目
- pom.xml添加Spring的依赖
- resources下添加applicationContext.xml
- 添加BookDao、BookDaoImpl、BookService、BookServiceImpl类
注解开发定义bean
//相当于给bean起了一个id,注解在哪个类上,class就是该类的类全名
@Component("bookDao")
public class BookServiceImpl implements BookService {
public void save() {
System.out.println("Book Service save..");
}
}
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com"/>
</beans>
说明:
base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
- 如果不起名称,会有一个默认值就是当前类名首字母小写,所以也可以按照名称获取。
- 使用该注解后,可以按照类型来获取对象。前提是该类型只存在一个对象
名称 |
@Component/@Controller/@Service/@Repository
|
类型 |
类注解
|
位置 |
类定义上方
|
作用 |
设置该类为
spring
管理的
bean
|
属性 |
value
(默认):定义
bean
的
id
|
纯注解开发
Spring 3.0 开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道
实现思路:将配置文件applicationContext.xml删除掉,使用类来替换。
实现步骤
步骤一:创建配置类 SpringConfig
//创建配置类
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
步骤四:创建运行类执行
public class Test {
public static void main(String[] args) {
加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDaoImpl bookDao = ctx.getBean(BookDaoImpl.class);
bookDao.save();
}
}
纯注解开发主要内容
- Java类替换Spring核心配置文件
- @Configuration注解用于设定当前类为配置类
- @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({"com.itheima.service" , "com.itheima.dao"})
- 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
注解开发Bean作用范围和生命周期管理
Bean的作用范围
在注解开发Bean 的配置环境下,默认bean为单例模式
//默认为单例模式,所以 两个对象属于同一对象
public class Test {
public static void main(String[] args) {
加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDaoImpl bookDao1 = ctx.getBean(BookDaoImpl.class);
BookDaoImpl bookDao2 = ctx.getBean(BookDaoImpl.class);
System.out.println(bookDao1);
System.out.println(bookDao2);
}
}
Bean的生命周期
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save(){
System.out.println("book Dao save..");
}
public void init(){
System.out.println("init..");
}
public void destory(){
System.out.println("destory..");
}
}
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save(){
System.out.println("book Dao save..");
}
@PostConstruct 在构造方法之后执行,替换 init-method
public void init(){
System.out.println("init..");
}
@PreDestroy //在销毁方法之前执行,替换 destroy-method
public void destory(){
System.out.println("destory..");
}
}
AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);
注解开发依赖注入
创建一个 Maven 项目pom.xml 添加 Spring 的依赖添加一个配置类 SpringConfig添加 BookDao 、 BookDaoImpl 、 BookService 、 BookServiceImpl 类
注解实现按照类型注入
@Service
public class BookServiceImpl implements BookService {
//注解开发实现自动装配
@Autowired
private BookDao bookDao;
public void save() {
bookDao.save();
System.out.println("Book Service save..");
}
}
注意
- 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
- 普通反射只能获取public修饰的内容
- 暴力反射除了获取public修饰的内容还可以获取private修改的内容
- 所以此处无需提供setter方法
(2)@Autowored按照类型注入,那么BookDao接口如果有多个实现类,那么再按照类型搜索就会报错。故一个接口若有多个实现类,就需要使用按照名称注入
注解实现按照名称注入
@Service
public class BookServiceImpl implements BookService {
//注解开发实现自动装配
@Autowired
@Qualifier("bookDaoImpl")
private BookDao bookDao;
public void save() {
bookDao.save();
System.out.println("Book Service save..");
}
}
简单数据类型注入
@Component("bookDaoImpl")
public class BookDaoImpl implements BookDao {
@Value("zhangsan")
private String name;
public void save(){
System.out.println("book Dao save..");
}
@PostConstruct 在构造方法之后执行,替换 init-method
public void init(){
System.out.println("init..");
}
@PreDestroy //在销毁方法之前执行,替换 destroy-method
public void destory(){
System.out.println("destory..");
}
}
注意数据格式要匹配,如将"abc"注入给int值,这样程序就会报错
注解读取properties配置文件
@value 一般杯用在从properties配置文件中读取内容
步骤1:resource下准备properties文件 jdbc.properties
name=itheima888
步骤2: 使用注解加载properties配置文件
在配置类上添加@PropertySource注解
@Configuration
@ComponentScan("com.itheima")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
步骤3:使用@Value读取配置文件中的内容
@Component("bookDaoImpl")
public class BookDaoImpl implements BookDao {
@Value("${name}")
private String name;
public void save(){
System.out.println("book Dao save.." + name);
}
@PostConstruct 在构造方法之后执行,替换 init-method
public void init(){System.out.println("init..");}
@PreDestroy //在销毁方法之前执行,替换 destroy-method
public void destory(){System.out.println("destory..");}
}
注意
- 如果读取的properties配置文件有多个,可以使用@PropertySource的属性来指定多个
@PropertySource({"jdbc.properties","xxx.properties"})
- @PropertySource注解属性中不支持使用通配符* ,运行会报错
@PropertySource({"*.properties"})
- @PropertySource注解属性中可以把classpath:加上,代表从当前项目的根路径找文件
@PropertySource({"classpath:jdbc.properties"})
小结
- 记住@Component、@Controller、@Service、@Repository这四个注解
- applicationContext.xml中<context:component-san/>的作用是指定扫描包路径,注解为 @ComponentScan
- @Configuration标识该类为配置类,使用类替换applicationContext.xml文件
- ClassPathXmlApplicationContext是加载XML配置文件
- AnnotationConfigApplicationContext是加载配置类(用于注解开发)
bean的作用范围和生命周期
掌握三个注解:
- @scope:设置创建出的bean是否为单例对象
- @PostConstruct:设置该方法为初始化方法,位于方法上
- @PreDestory:设置该方法为销毁方法,位于方法上
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
注解开发依赖注入
- @Autowired:自动装配,为引用类型属性设置值
- @Qualifier:为引用类型属性指定注入的beanId,必须搭配@Autowired使用且必须在其下方
- @Value:为 基本数据类型 或 字符串类型 属性设置值
- @PropertySource:位于配置类上方,用于加载properties文件中的属性值