纯注解开发我们前面所提到的注解开发属于2.5的附属版本
在Spring3.0版本,Spring就提供了纯注解开发模式,利用java类代替配置文件,开启了Spring快速开发时代
在之前我们的xml配置文件是很繁琐的:
<!--原生xml配置文件--><?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/></beans>
但是我们可以通过创建单独的类来表示配置文件:
- @Configuration:用于声明当前类为Spring配置类
- @ComponentScan:用于扫描类文件(类似于<context:component-scan base-package="com.itheima"/>)
package com.itheima.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;//声明当前类为Spring配置类@Configuration//设置bean扫描路径,多个路径书写为字符串数组格式@ComponentScan({"com.itheima.service","com.itheima.dao"})public class SpringConfig {}
注意:因为该类属于配置类 , 我们通常单列一个文件夹来表示因为我们的开发不再依靠于xml配置文件,所以在主函数中的Spring容器获得方式也发生了改变:
常用文件夹:config
命名规范:SpringConfig,UserConfig...
package com.itheima;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 这是我们之前的获取方式,采用路径获取xml文件// ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");// 这是新的获取方式,直接提供配置类的类型// AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);// 后面操作无需变化BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);//按类型获取beanBookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}}
注解开发Bean作用范围与管理既然我们的Bean开发从xml转移到注解开发,那么一些配置设置同样发生改变首先我们介绍Scope范围的设置方式:
- @Scope:定义bean的作用范围
package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Repository;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;@Repository//@Scope设置bean的作用范围(singleton或prototype),可以不添加默认singleton@Scope("singleton")public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}
然后我们介绍一下bean生命周期的init和destroy操作:- @PostConstruct:定义init操作,表示构造后操作
- @PreDestroy:定义destroy操作,表示销毁前操作
- 使用@Autowired注解开启自动装配模式(按类型)
- 当存在相同类型时,我们采用@Qualifier开启按名自动装配
package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;@Servicepublic class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowired//@Qualifier:自动装配bean时按bean名称装配@Qualifier("bookDao")private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}}
注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法除了上述的bean类型装配,我们的简单类型装配依旧存在:
注意:自动转配建议使用无参构造方法创建对象(默认) , 如果不提供对应构造方法,请提供唯一的构造方法
注意:@Qualifier是基于@Autowired实现的,必须保证先有Autowired才能存在Qualifier