1、半注解开发
Spring注解开发是指使用注解来配置和管理Spring框架中的各种组件和功能。
通过使用注解,我们可以在代码中直接声明和配置Spring的bean、依赖注入、AOP切面等,并且减少了传统XML配置文件的使用。
采用注解的方式开发步骤:
1.在类上使用注解
2、在applicationContext.xml中基包扫描,扫描指定包和它的子包的类
代码演示
1、在所有需要放到容器中的类,在类上使用@Component注解
@Component
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("book dao save");
}
}
2、核心配置文件中通过基包扫描加载bean(会扫描这个包和它所有的子包)
<context:component-scan base-package="org.demo"/>
Spring提供@Component注解的三个衍生注解:
- @Controller:用于标识表现层bean定义
- @Service:用于标识业务层bean定义
- @Repository:用于标识数据层bean定义
2、全注解开发
上面的例子虽然是采用注解开发,但还是在application.xml配置了扫描包
Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道
使用说明
- @Configuration注解用于设定当前类为配置类
- @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({com.demo.service","com.demo.dao"})
- 取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
代码演示
1、定义配置类代替配置文件
@Configuration
@ComponentScan("org.demo")
public class SpringConfig {
}
2、在测试类中加载配置类,获取Bean对象并使用
public class Main {
public static void main(String[] args) {
//1、创建IOC容器
AnnotationConfigApplicationContext aac = new AnnotationConfigApplicationContext(SpringConfig.class);
//2、获取bean对象
BookService bean = aac.getBean(BookService.class);
//3、调用方法
bean.save();
//4、关闭容器
aac.close();
}
}
3、bean的作用范围注解
bean作用范围注解配置
- 使用@Scope定义bean作用范围
@Component
@Scope("singleton")
public class BookUtils {
}
bean生命周期注解配置
- 使用@PostConstruct、@PreDestroy定义bean生命周期
@Component
@Scope("singleton")
public class BookUtils {
public BookUtils() {
System.out.println("book constructor ...");
}
@PostConstruct
public void init(){
System.out.println("book init ...");
}
@PreDestroy
public void destroy(){
System.out.println("book destory ...");
}
}
注意:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk9开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
- 测试类
@Test
public void testPureAnnotation() {
//AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookUtils bookUtils = (BookUtils) ctx.getBean("bookUtils");
System.out.println(bookUtils);
//关闭容器
ctx.close();
}
4、依赖注入
使用@Autowired注解开启自动装配模式(默认按类型,如果有多个类型相同的按名称)
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public void save() {
System.out.println("bookService 保存数据");
bookDao.save();
}
}
注意:
- 自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法
- 自动装配建议使用无参构造方法创建对象(默认)
使用@Qualifier注解开启指定名称装配bean
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao")
private BookDao bookDao;
@Override
public void save() {
System.out.println("bookService 保存数据");
bookDao.save();
}
}
不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。
@Autowired默认按照类型自动装配,如果IoC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称
简单类型注入
使用@Value实现简单类型注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
//@Value:注入简单类型(无需提供set方法)
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
使用@PropertySource注解加载properties文件,在配置类上面
@Configuration
@ComponentScan("org.demo")
@PropertySource("classpath:DataSource.properties")
public class SpringConfig {
}
注意:路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*
@Component
public class BookUtils {
@Value("${name}")
private String num;
@Override
public String toString() {
return "BookUtils{" +
"num=" + num +
'}';
}
}
5、注解导入第三方bean
方式一:使用@Bean配置第三方bean
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/spring_db?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true");
druidDataSource.setUsername("root");
druidDataSource.setPassword("123456");
return druidDataSource;
}
方式二:将独立的配置类加入核心配置
@Configuration
public class JdbcConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
//相关配置
return ds;
}
}
使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式
@Configuration
@Import(JdbcConfig.class)
public class SpringConfig {
}
6、第三方Bean注入资源
简单类型依赖注入
public class JdbcConfig {
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://localhost:3306/spring_db")
private String url;
@Value("root")
private String userName;
@Value("123456")
private String password;
//1.定义一个方法获得要管理的对象
//2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
说明:如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。
引用类型依赖注入
//Spring会自动从IOC容器中找到BookDao对象赋值给参数bookDao变量,如果没有就会报错。
@Bean
public DataSource dataSource(BookDao bookDao){
System.out.println(bookDao);
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
说明:引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象