11 注解开发
11.1 注解开发定义Bean
- 代码
- 接口BookDao
public interface BookDao {
void save();
}
- 实现类BookDaoImpl【更改之处】
在最上面@Component(“bookDao”)
@Component("bookDao")
//或者@Repository("bookDao")
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save");
}
}
- App实现类
public class App2 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
}
}
- 配置文件【更改之处】
加上扫描包
<context:component-scan base-package="com.itheima.dao.impl"/>
或者范围更大一些
<context:component-scan base-package="com.itheima"/>
- 另一种方式
- BookService接口
public interface BookService {
void save();
}
- BookServiceImpl接口实现类【更改之处】
Component不指定类名
@Component
//或者@Service
public class BookServiceImpl implements BookService {
//删除业务层中使用new的方式创建的dao对象
private BookDao bookDao;
// private BookDao bookDao = new BookDaoImpl();
public void save(){
System.out.println("book service save ...");
bookDao.save();
}
//生成set方法
void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
- App入口类【更改之处】
ctx.getBean(BookService.class)
public class App2 {
public static void main(String[] args) {
//3.获取IoC容器,ApplicationContext和配置一样,new一个接口实现类
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
- 配置文件
<context:component-scan base-package="com.itheima"/>
- 衍生注解
- 对于业务层,使用@Service
- 对于数据层,使用@Repository
- 对于表现层,使用@Controller
11.2 纯注解开发
- 概述
新建配置类后,使用@Configuration替换配置文件外面的壳子
使用@ComponentScan(“com.itheima”)代替<context:component-scan base-package=“com.itheima”/>
- 代码
- SpringConfig配置类【更改之处】
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
- App实现类【更改之处】
加载配置类AnnotationConfigApplicationContext
public class App3 {
public static void main(String[] args) {
//1.加载配置类
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
}
}
- 运行结果
com.itheima.dao.impl.BookDaoImpl@15bb6bea
com.itheima.service.impl.BookServiceImpl@41ee392b
Process finished with exit code 0
- 注意事项
多个用大括号
12 bean管理
12.1 bean作用范围
- 代码背景
- interface接口
public interface BookDao {
void save();
}
- BookDaoImpl实现类
@Repository
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save");
}
}
- 配置类
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
- App实现
public class App3 {
public static void main(String[] args) {
//1.加载配置类
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao1 = (BookDao) ctx.getBean(BookDao.class);
BookDao bookDao2 = (BookDao) ctx.getBean(BookDao.class);
System.out.println(bookDao1);
System.out.println(bookDao2);
}
}
- 结果
是单例
com.itheima.dao.impl.BookDaoImpl@57d5872c
com.itheima.dao.impl.BookDaoImpl@57d5872c
Process finished with exit code 0
- 配置非单例对象
- 在BookDaoImpl接口实现类添加@Scope(“prototype”)
@Repository
@Scope("prototype")
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save");
}
}
- 运行结果
com.itheima.dao.impl.BookDaoImpl@52aa2946
com.itheima.dao.impl.BookDaoImpl@4de5031f
Process finished with exit code 0
12.2 bean生命周期
- 增加生命周期方法
- 接口实现类
增加方法以及注释,@PostConstruct在构造方法后,@PreDestroy在销毁之前
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save");
}
//在构造方法后
@PostConstruct
public void init(){
System.out.println("init ...");
}
//在销毁之前
@PreDestroy
public void destory(){
System.out.println("destory ...");
}
}
- 关闭APP入口类的容器
记得使用AnnotationConfigApplicationContext
public class App3 {
public static void main(String[] args) {
//1.加载配置类
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao1 = (BookDao) ctx.getBean(BookDao.class);
BookDao bookDao2 = (BookDao) ctx.getBean(BookDao.class);
System.out.println(bookDao1);
System.out.println(bookDao2);
ctx.close();
}
}
13 自动装配
-
注入对象
使用 @Autowired注入对象,使用类型自动装配,set方法也可以不要,原因是使用了反射中的暴力反射对私有属性初始化数据
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public void save(){
System.out.println("book service save ...");
bookDao.save();
}
//生成set方法
//public void setBookDao(BookDao bookDao) {
//this.bookDao = bookDao;
//}
}
但是如果出现两个BookDao的类型,需要使用名字自动装载,如下
@Repository("bookDao")
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save");
}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao{
public void save(){
System.out.println("book dao save2");
}
}
- BookServiceImpl接口实现类
@Qualifier(“bookDao2”)区分哪一个
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao2")
private BookDao bookDao;
public void save(){
System.out.println("book service save ...");
bookDao.save();
}
}
- 简单类型
- BookDaoImpl【更改之处】
使用@Value(“itheima”)可以进行简单类型的注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao{
@Value("itheima")
private String name;
public void save(){
System.out.println("book dao save"+name);
}
}
- BookServiceImpl
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao")
private BookDao bookDao;
public void save(){
System.out.println("book service save ...");
bookDao.save();
}
}
- App入口
public class App3 {
public static void main(String[] args) {
//1.加载配置类
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookService = ctx.getBean(BookService.class);
bookService.save();
}
}
- 运行结果
book service save ...
book dao save itheima
Process finished with exit code 0
- 外部properties的name
- 在配置类中加载属性
@PropertySource(“jdbc.properties”)
@Configuration
@ComponentScan("com.itheima")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
- 简单类型指定引用
@Repository("bookDao")
public class BookDaoImpl implements BookDao{
@Value("${name}")
private String name;
public void save(){
System.out.println("book dao save "+name);
}
}
- 结果
book service save ...
book dao save itheima888
Process finished with exit code 0
多个配置文件用数组,不支持通配符*
- 总结
- 自动装配
- @Autowired
- @Qualifier
- @Value
- 读取properties文件
- @Properties
14 第三方bean管理
14.1 Druid的数据源bean管理
- Druid的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
- 写一个专门的类进行设置
@Bean
public class JdbcConfig {
//1.定义一个方法获得要管理的对象
//2.添加@Bean,表示当前方法的返回值
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
- 在配置中导入JdbcConfig类
@Import({JdbcConfig.class})
@Configuration
@Import({JdbcConfig.class})
public class SpringConfig {
}
- 在App入口处写上
public class App3 {
public static void main(String[] args) {
//1.加载配置类
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource);
}
}
- 运行结果
{
CreateTime:"2022-11-07 21:08:01",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}
14.2 第三方bean注入资源
- 背景
- 如果第三方bean例如Druid注入的时候缺少几个条件,或者是内容是要来自于配置文件
- 简单数据类型
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("root")
private String password;
//1.定义一个方法获得要管理的对象
//2.添加@Bean,表示当前方法的返回值
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
- 引用类型
- BookDaoImpl
@Repository("bookDao")
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save ");
}
}
- 把ComponentScan打开
@Configuration
@ComponentScan("com.itheima.impl")
@Import({JdbcConfig.class})
public class SpringConfig {
}
- 把BookDao注入JdbcConfig类中
public DataSource dataSource(BookDao bookDao),把形参写进去,进行了自动装配,在容器中找到了
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("root")
private String password;
//1.定义一个方法获得要管理的对象
//2.添加@Bean,表示当前方法的返回值
@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;
}
}
- 运行结果
com.itheima.impl.BookDaoImpl@2b546384
{
CreateTime:"2022-11-07 22:19:15",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}
Process finished with exit code 0