文章目录
- Spring
-
- 系统架构
- Spring核心概念
-
- 目前项目中的问题
- IOC控制反转
- DI(Dependency Injection)依赖注入
- Spring入门案例
-
- IOC入门案例
- DI入门案例
- IOC相关内容
-
- bean基础配置
-
- id与class
- name属性
- bean作用范围scope配置
- bean实例化
-
- 环境准备
- 构造方法实例化
- 静态工厂实例化
- 实例工厂与FactoryBean
- 小结:构造方法(常用),静态工厂+实例工厂(了解)
- bean的生命周期
-
- 生命周期设置
- close关闭容器
- 注册钩子关闭容器
- DI相关内容
-
- setter注入
-
- 环境注入
- 注入引用数据类型
- 注入简单数据类型
- 构造器注入
-
- 环境准备
- 构造器注入引用数据类型
- 构造器注入多个引用数据类型
- 构造器注入多个简单数据类型
- 自动配置
-
- 依赖自动装配
- 自动装配方式
- 准备环境
- 完成自动装配的配置
- 集合注入
-
- 环境准备
- 注入数组类型数据
- 注入List类型数据
- 注入Set类型数据
- 注入Map类型数据
- 注入Properties类型数据
- IOC/DI配置管理第三方bean
-
- 案例:数据源对象管理
-
- 环境准备
- 思路分析
- 实现Druid管理
- 加载properties文件
-
- 第三方bean属性优化
- 当有多个properties配置文件需要被加载
- 核心容器
-
- 环境准备
- 容器
-
- 容器的创建方式
- Bean的三种获取方式
- BeanFactory的使用
- IOC/DI注解开发
-
- 环境准备
- 注解开发定义bean
- 纯注解开发模式
-
- 实现步骤
- 注解开发Bean作用范围与生命周期管理
- 注解开发依赖注入
-
- 注解实现按照类型注入
- 注解实现按照名称注入
- 简单数据类型注入
- 注解读取properties配置文件
- IOC/DI注解开发管理第三方bean
-
- 环境准备
- 注解开发管理第三方bean
- 引入外部配置类
-
- 使用包扫描引入
- 使用`@Import`引入
- 注解开发实现为第三方bean注入资源
-
- 简单数据类型
Spring
系统架构
- 核心层
Core Container:核心容器,这个模块是Spring最核心的模块,其他的都需要依赖该模块 - AOP层
AOP:面向切面编程,它依赖核心层容器,目的是在不改变原有代码的前提下对其进行功能增强
Aspects:AOP是思想,Aspects是对AOP思想的具体实现 - 数据层
Data Access:数据访问,Spring全家桶中有对数据访问的具体实现技术
Data Integration:数据集成,Spring支持整合其他的数据层解决方案,比如Mybatis
Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现,也是后期学习的重点内容 - Web层
- Test层
Spring主要整合了Junit来完成单元测试和集成测试
Spring核心概念
目前项目中的问题
耦合度偏高
Spring的解决方案:在程序中不要主动使用new产生对象,转换为由外部提供对象
IOC控制反转
控制反转:使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部
Spring和IOC之间的关系
- Spring技术对IOC思想进行了实现
- Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的"外部"
- IOC思想中的外部指的就是Spring的IOC容器
IOC容器的作用以及内部存放
- IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
- 被创建或被管理的对象在IOC容器中统称为Bean
- IOC容器中放的就是一个个的Bean对象
当IOC容器中创建好service和dao对象后,程序能正确执行吗?
- 不行,因为service运行需要依赖dao对象
- IOC容器中虽然有service和dao对象
- 但是service对象和dao对象没有任何关系
- 需要把dao对象交给service,也就是说要绑定service和dao对象之间的关系
在容器中建立对象与对象之间的绑定关系就要用到DI
DI(Dependency Injection)依赖注入
依赖注入:在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
Spring入门案例
IOC入门案例
- 创建Maven的java项目
- pom.xml添加Spring的依赖jar包
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>
- 创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
public interface BookDao {public void save);
}public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ...");}
}public interface BookService {public void save);
}public class BookServiceImpl implements BookService {private BookDao bookDao = new BookDaoImpl);public void save) {System.out.println"book service save ...");bookDao.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"xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"><!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型--><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
</beans>
注意事项:bean定义时id属性在同一个上下文中配置文件)不能重复
- 使用Spring提供的接口完成IOC容器的创建
public class App {public static void mainString[] args) {//获取IOC容器ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");}
}
- 从容器中获取对象进行方法调用
public class App {public static void mainString[] args) {//获取IOC容器ApplicationContext ctx = new
ClassPathXmlApplicationContext"applicationContext.xml");
// BookDao bookDao = BookDao) ctx.getBean"bookDao");
// bookDao.save);BookService bookService = BookService) ctx.getBean"bookService");bookService.save);}
}
IOC入门案例已经完成,但bookService中仍有对bookDao的new操作,耦合度还是比较高,可以用到以下的DI:依赖注入
DI入门案例
- 去除代码中的new
public class BookServiceImpl implements BookService {//删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save) {System.out.println"book service save ...");bookDao.save);}
}
- 在业务层提供BookDao的setter方法
public class BookServiceImpl implements BookService {//删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save) {System.out.println"book service save ...");bookDao.save);}//提供对应的set方法public void setBookDaoBookDao bookDao) {this.bookDao = bookDao;}
}
- 在配置文件中添加依赖注入的配置
<?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标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型--><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><!--配置server与dao的关系--><!--property标签表示配置当前bean的属性name属性表示配置哪一个具体的属性ref属性表示参照哪一个bean--><property name="bookDao" ref="bookDao"/></bean>
</beans>
- name="bookDao"中bookDao的作用是让Spring的IOC容器在获取到名称后,将首字母大写,前面加set找对应的setBookDao)方法进行对象注入
- ref="bookDao"中bookDao的作用是让Spring能在IOC容器中找到id为bookDao的Bean对象给bookService进行注入
- 运行程序调用方法
IOC相关内容
bean基础配置
id与class
class属性应写接口的实现类的全路径类名,不能写接口的全路径类名
name属性
name:别名
<!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔-->
<!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype--><bean id="bookService" name="service service4 bookEbi"
class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/>
</bean>
ref属性指定的bean必须在容器中存在
ref的属性值,页可以是另一个bean的name属性值,但是还是建议以id进行注入
bean作用范围scope配置
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" scope="prototype">
默认情况下,Spring创建的bean对象都是单例的
如下创建的两个bookDao实例相同,即bean对象是单例的
public class AppForScope {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao1 = BookDao) ctx.getBean"bookDao");BookDao bookDao2 = BookDao) ctx.getBean"bookDao");System.out.printlnbookDao1);System.out.printlnbookDao2);}
}
将scope设置为singleton
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"
scope="singleton"/>
与上述相同
将scope设置为prototype
创建的两个实例不同
- singleton默认为单例
- prototype为非单例
- bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
- bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
- 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
- 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。
bean实例化
环境准备
- 添加maven项目
- pom.xml添加依赖
- resources下添加spring的配置文件applicationContext.xml
构造方法实例化
- 准备需要被创建的类
public interface BookDao {public void save);
}
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ...");}
}
- 将类配置到Spring容器
<?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>
- 编写运行程序
public class AppForInstanceBook {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao = BookDao) ctx.getBean"bookDao");bookDao.save);}
}
- 类中提供构造函数测试
public class BookDaoImpl implements BookDao {public BookDaoImpl) {System.out.println"book dao constructor is running ....");}public void save) {System.out.println"book dao save ...");}
}
控制台中有打印构造函数的输出,甚至将构造函数改成private后仍有输出,因此Spring底层用的是类的无参构造方法
静态工厂实例化
静态工厂方法创建bean:
- 准备接口和实现类
public interface OrderDao {public void save);
}
public class OrderDaoImpl implements OrderDao {public void save) {System.out.println"order dao save ...");}
}
- 创建一个工厂类OrderDaoFactory并提供一个静态方法
//静态工厂创建对象
public class OrderDaoFactory {public static OrderDao getOrderDao){return new OrderDaoImpl);}
}
- 编写AppForInstanceOrder运行类,在类中通过工厂获取对象
public class AppForInstanceOrder {public static void mainString[] args) {//通过静态工厂创建对象OrderDao orderDao = OrderDaoFactory.getOrderDao);orderDao.save);}
}
静态工厂实例化:
- 在spring的配置文件application.properties中添加以下内容
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
- 在AppForInstanceOrder运行类,使用从IOC容器中获取bean的方法进行运行测试
public class AppForInstanceOrder {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");OrderDao orderDao = OrderDao) ctx.getBean"orderDao");orderDao.save);}
}
实例工厂与FactoryBean
- 准备一个UserDao和UserDaoImpl类
public interface UserDao {public void save);
}
public class UserDaoImpl implements UserDao {public void save) {System.out.println"user dao save ...");}
}
- 创建一个工厂类OrderDaoFactory并提供一个普通方法
public class UserDaoFactory {public UserDao getUserDao){return new UserDaoImpl);
}
}
- 编写AppForInstanceUser运行类,在类中通过工厂获取对象
public class AppForInstanceUser {public static void mainString[] args) {//创建实例工厂对象UserDaoFactory userDaoFactory = new UserDaoFactory);//通过实例工厂对象创建对象UserDao userDao = userDaoFactory.getUserDao);userDao.save);
}
实例工厂实例化
- 在spring的配置文件中添加
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
- 在AppForInstanceUser运行类,使用从IOC容器中获取bean的方法进行运行测试
public class AppForInstanceUser {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");UserDao userDao = UserDao) ctx.getBean"userDao");userDao.save);}
}
FactoryBean的使用
- 创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法public UserDao getObject) throws Exception {return new UserDaoImpl);}//返回所创建类的Class对象public Class<?> getObjectType) {return UserDao.class;}
}
- 在Spring的配置文件中进行配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
小结:构造方法(常用),静态工厂+实例工厂(了解)
bean的生命周期
bean的生命周期:从对象创建到销毁的整体过程
生命周期设置
- 添加初始化和销毁方法
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ...");}//表示bean初始化对应的操作public void init){System.out.println"init...");}//表示bean销毁前对应的操作public void destory){System.out.println"destory...");}
}
- 配置生命周期
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init"
destroy-method="destory"/>
- Spring的IOC容器是运行在JVM中
- 运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行
- main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了
- 所以没有调用对应的destroy方法
close关闭容器
ApplicationContext中没有close方法
需要将ApplicationContext更换成ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");
调用ctx的close)方法
ctx.close);
运行程序,就能执行destroy方法的内容
注册钩子关闭容器
在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
调用ctx的registerShutdownHook)方法
ctx.registerShutdownHook);
不同点:close)是在调用的时候关闭,registerShutdownHook)是在JVM退出前调用关闭。
Spring提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置init-method和destroy-method
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {private BookDao bookDao;public void setBookDaoBookDao bookDao) {this.bookDao = bookDao;}public void save) {System.out.println"book service save ...");bookDao.save);}public void destroy) throws Exception {System.out.println"service destroy");}public void afterPropertiesSet) throws Exception {System.out.println"service init");}
}
- 先进行bookDao中的初始化init并注入属性
- 进行bookService中的afterPropertiesSet
- 然后才是执行中间语句
- 而后先是bookService destroy
- 最后才是bookDao destroy
对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
- 初始化容器
- 创建对象内存分配)
- 执行构造方法
- 执行属性注入set操作)
- 执行bean初始化方法
- 使用bean
- 执行业务操作
- 关闭/销毁容器
- 执行bean销毁方法
DI相关内容
setter注入
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDaoBookDao bookDao) {this.bookDao = bookDao;}
}
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.itheima.dao.imipl.BookDaoImpl"/>
环境注入
创建一个Maven项目
pom.xml添加依赖
resources下添加spring的配置文件
注入引用数据类型
需求:在bookServiceImpl对象中注入userDao
- 在BookServiceImpl中声明userDao属性(只声明不需要new)
- 为userDao属性提供setter方法(再bookServiceImpl类中添加setUserDao方法:this.……=……)
- 在配置文件中使用property标签注入
注入简单数据类型
需求:给BookDaoImpl注入一些简单数据类型的数据
- 在BookDaoImpl类中声明对应的简单数据类型的属性
- 为这些属性提供对应的setter方法
- 在applicationContext.xml中配置
public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;public void setConnectionNumint connectionNum) {this.connectionNum = connectionNum;}public void setDatabaseNameString databaseName) {this.databaseName = databaseName;}public void save) {System.out.println"book dao save..."+databaseName+","+connectionNum);}
}
<?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"><property name="databaseName" value="mysql"/><property name="connectionNum" value="10"/></bean><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/><property name="userDao" ref="userDao"/>
</bean>
value:后面跟的是简单数据类型,对于参数类型,Spring在注入的时候会自动转换,但是不能写成
<property name="connectionNum" value="abc"/>
这样的话,spring在将abc转换成int类型的时候就会报错。
构造器注入
环境准备
创建一个Maven项目
pom.xml添加依赖
resources下添加spring的配置文件
需要创建接口实现类+spring配置文件+运行类和之前相同
构造器注入引用数据类型
需求:将BookServiceImpl类中的bookDao修改成使用构造器的方式注入。
- 将bookDao的setter方法删除掉
- 添加带有bookDao参数的构造方法
- 在applicationContext.xml中配置
- 在BookServiceImpl类中将bookDao的setter方法删除掉,并添加带有bookDao参数的构造方法
public class BookServiceImpl implements BookService{private BookDao bookDao;public BookServiceImplBookDao bookDao) {this.bookDao = bookDao;}public void save) {System.out.println"book service save ...");bookDao.save);}
}
- 配置文件中进行配置构造方式注入,在applicationContext.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"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/></bean>
</beans>
name属性对应的值为构造函数中方法形参的参数名,必须要保持一致。
ref属性指向的是spring的IOC容器中其他bean对象。
构造器注入多个引用数据类型
需求:在BookServiceImpl使用构造函数注入多个引用数据类型,比如userDao
- 声明userDao属性
- 生成一个带有bookDao和userDao参数的构造函数
- 在applicationContext.xml中配置注入
- 在BookServiceImpl声明userDao并提供多个参数的构造函数
public class BookServiceImpl implements BookService{private BookDao bookDao;private UserDao userDao;public BookServiceImplBookDao bookDao,UserDao userDao) {this.bookDao = bookDao;this.userDao = userDao;}public void save) {System.out.println"book service save ...");bookDao.save);userDao.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"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"/><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/><constructor-arg name="userDao" ref="userDao"/></bean>
</beans>
构造器注入多个简单数据类型
需求:在BookDaoImpl中,使用构造函数注入databaseName和connectionNum两个参数。
1.提供一个包含这两个参数的构造方法
2.在applicationContext.xml中进行注入配置
- 修改BookDaoImpl类,添加构造方法
public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;public BookDaoImplString databaseName, int connectionNum) {this.databaseName = databaseName;this.connectionNum = connectionNum;}public void save) {System.out.println"book dao save..."+databaseName+","+connectionNum);}
}
- 在applicationContext.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"><constructor-arg name="databaseName" value="mysql"/><constructor-arg name="connectionNum" value="666"/></bean><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/><constructor-arg name="userDao" ref="userDao"/></bean>
</beans>
当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变
这两块存在紧耦合,具体该如何解决?
方式一:删除name属性,添加type属性,按照类型注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><constructor-arg type="int" value="10"/><constructor-arg type="java.lang.String" value="mysql"/>
</bean>
这种方式可以解决构造函数形参名发生变化带来的耦合问题
但是如果构造方法参数中有类型相同的参数,这种方式就不太好实现了
方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><constructor-arg index="1" value="100"/><constructor-arg index="0" value="mysql"/>
</bean>
这种方式可以解决参数类型重复问题
但是如果构造方法参数顺序发生变化后,这种方式又带来了耦合问题
自己开发的模块推荐使用setter注入
自动配置
依赖自动装配
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
自动装配方式
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
准备环境
创建一个Maven项目
pom.xml添加依赖
resources下添加spring的配置文件
需要创建接口实现类+spring配置文件+运行类和之前相同
完成自动装配的配置
修改applicationContext.xml配置文件:
将 <property>
标签删除,在<bean>
标签中添加autowire属性
<?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 class="com.itheima.dao.impl.BookDaoImpl"/><!--autowire属性:开启自动装配,通常使用按类型装配--><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"
autowire="byType"/>
</beans>
注意事项:
- 需要注入属性的类中对应属性的setter方法不能省略
- 被注入的对象必须要被Spring的IOC容器管理
- 按照类型在Spring的IOC容器中如果找到多个对象,会报NoUniqueBeanDefinitionException
一个类型在IOC中有多个对象,还想要注入成功,这个时候就需要按照名称注入,配置方式为:
<?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 class="com.itheima.dao.impl.BookDaoImpl"/><!--autowire属性:开启自动装配,通常使用按类型装配--><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"
autowire="byName"/>
</beans>
- 外部类只能通过属性的set方法进行访问
- 对外部类来说,setBookDao方法名,去掉set后首字母小写是其属性名
- 如果找不到则注入Null
当某一个类型在IOC容器中有多个对象,按照名称注入只找其指定名称对应的bean对象,不会报错以后用的更多的是按照类型注入
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
集合注入
环境准备
创建一个Maven项目
pom.xml添加依赖
resources下添加spring的配置文件
- 添加BookDao、BookDaoImpl类
public interface BookDao {public void save);
}
public class BookDaoImpl implements BookDao {private int[] array;private List<String> list;private Set<String> set;private Map<String,String> map;private Properties properties;public void save) {System.out.println"book dao save ...");System.out.println"遍历数组:" + Arrays.toStringarray));System.out.println"遍历List" + list);System.out.println"遍历Set" + set);System.out.println"遍历Map" + map);System.out.println"遍历Properties" + properties);}//setter....方法省略,自己使用工具生成
}
- resources下提供spring的配置文件,applicationContext.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>
- 编写AppForDICollection运行类,加载Spring的IOC容器,并从中获取对应的bean对象
public class AppForDICollection {public static void main String[] args ) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao = BookDao) ctx.getBean"bookDao");bookDao.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"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"><property name="array"><array><value>100</value><value>200</value><value>300</value></array></property></bean>
</beans>
注入List类型数据
<?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"><property name="list"><list><value>itcast</value><value>itheima</value><value>boxuegu</value><value>chuanzhihui</value></list></property></bean>
</beans>
注入Set类型数据
<?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"><property name="set"><set><value>itcast</value><value>itheima</value><value>boxuegu</value><value>boxuegu</value></set></property></bean>
</beans>
注入Map类型数据
<?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"><property name="map"><map><entry key="country" value="china"/><entry key="province" value="henan"/><entry key="city" value="kaifeng"/></map></property></bean>
</beans>
注入Properties类型数据
<?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"><property name="properties"><props><prop key="country">china</prop><prop key="province">henan</prop><prop key="city">kaifeng</prop></props></property></bean>
</beans>
- property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写
<array>
、<list>
、<set>
、<map>
、<props>
标签- List的底层也是通过数组实现的,所以
<list>
和<array>
标签是可以混用 - 集合中要添加引用类型,只需要把
<value>
标签改成<ref>
标签,这种方式用的比较少
IOC/DI配置管理第三方bean
案例:数据源对象管理
环境准备
创建maven项目
pom.xml添加依赖
resources下添加spring的配置文件applicationContext.xml
编写运行类APP
思路分析
需求:使用Spring的IOC容器来管理Druid连接池对象
- 使用第三方的技术,需要在pom.xml添加依赖
- 在配置文件中将【第三方的类】制作成一个bean,让IOC容器进行管理
- 数据库连接需要基础的四要素驱动、连接、用户名和密码,【如何注入】到对应的bean中
- 从IOC容器中获取对应的bean对象,将其打印到控制台查看结果
实现Druid管理
- 导入druid的依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
</dependency>
- 配置第三方bean
<?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"><!--管理DruidDataSource对象--><bean class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/spring_db"/><property name="username" value="root"/><property name="password" value="root"/></bean>
</beans>
- driverClassName:数据库驱动
- url:数据库连接地址
- username:数据库连接用户名
- password:数据库连接密码
- 数据库连接的四要素要和自己使用的数据库信息一致。
- 从IOC容器中获取对应的bean对象
public class App {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");DataSource dataSource = DataSource) ctx.getBean"dataSource");System.out.printlndataSource);}
}
加载properties文件
第三方bean属性优化
需求:将数据库连接四要素提取到properties配置文件,spring来加载配置信息并使用这些信息来完成属性注入
- 在resources下创建一个jdbc.properties文件的名称可以任意)
- 将数据库连接四要素配置到配置文件中
- 在Spring的配置文件中加载properties文件
- 使用加载到的值实现属性注入
实现步骤
(1) 准备properties配置文件:resources下创建一个jdbc.properties文件,并添加对应的属性键值对
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root
(2) 在applicationContext.xml中开context命名空间,加载properties配置文件
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/springcontext.xsd">
</beans>
<context:property-placeholder location="jdbc.properties"/>
(3)使用${key}
来读取properties配置文件中的内容并完成属性注入
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/springcontext.xsd"><context:property-placeholder location="jdbc.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
</beans>
当有多个properties配置文件需要被加载
在resources下添加jdbc.properties , jdbc2.properties
<!--方式一 -->
<context:property-placeholderlocation="jdbc.properties,jdbc2.properties" system-propertiesmode="NEVER"/>
<!--方式二-->
<context:property-placeholder location="*.properties" systemproperties-mode="NEVER"/>
<!--方式三 -->
<context:property-placeholder location="classpath:*.properties"system-properties-mode="NEVER"/>
<!--方式四-->
<context:property-placeholder location="classpath*:*.properties"system-properties-mode="NEVER"/>
</beans>
- 方式一:可以实现,如果配置文件多的话,每个都需要配置
- 方式二: *.properties代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准
- 方式三:标准的写法,classpath:代表的是从根路径下开始查找,但是只能查询当前项目的根路径
- 方式四:不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件
核心容器
环境准备
- 创建一个Maven项目
- pom.xml添加Spring的依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
- resources下添加applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
- 添加BookDao和BookDaoImpl类
public interface BookDao {public void save);
}
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ..." );}
}
- 创建运行类App
public class App {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao = BookDao) ctx.getBean"bookDao");bookDao.save);}
}
容器
容器的创建方式
- 类路径下的XML配置文件
ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");
- 文件系统下的XML配置文件(耦合度较高,不推荐)
ApplicationContext ctx = newFileSystemXmlApplicationContext"applicationContext.xml");
Bean的三种获取方式
BookDao bookDao = BookDao) ctx.getBean"bookDao");
BookDao bookDao = ctx.getBean"bookDao",BookDao.class);
BookDao bookDao = ctx.getBeanBookDao.class);
BeanFactory的使用
使用BeanFactory来创建IOC容器
public class AppForBeanFactory {public static void mainString[] args) {Resource resources = new ClassPathResource"applicationContext.xml");BeanFactory bf = new XmlBeanFactoryresources);BookDao bookDao = bf.getBeanBookDao.class);bookDao.save);}
}
IOC/DI注解开发
环境准备
创建Maven项目
pom.xml添加Spring的依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
resources下添加applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
添加BookDao、BookDaoImpl、BookService、BookServiceImpl类
public interface BookDao {public void save);
}
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ..." );}
}
public interface BookService {public void save);
}
public class BookServiceImpl implements BookService {public void save) {System.out.println"book service save ...");}
}
创建运行类App
public class App {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao = BookDao) ctx.getBean"bookDao");bookDao.save);}
}
注解开发定义bean
- 删除原XML配置
将配置中的<bean>
标签删除掉
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
- Dao上添加注解
在BookDaoImpl类上添加@Component
注解(注解后String的相当于Bean的id即name)
@Component"bookDao")
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ..." );}
}
注意:@Component
注解不可以添加在接口上,因为接口是无法创建对象的。
- 配置Spring的注解包扫描
为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><context:component-scan base-package="com.itheima"/>
</beans>
component-scan
- component:组件,Spring将管理的bean视作自己的一个组件
- scan:扫描
- Service上添加注解
在BookServiceImpl类上也添加@Component交给Spring框架管理
@Component
注解如果不起名称,会有一个默认值就是当前类名首字母小写
@Component
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDaoBookDao bookDao) {this.bookDao = bookDao;}public void save) {System.out.println"book service save ...");bookDao.save);}
}
- 运行程序
public class App {public static void mainString[] args) {ApplicationContext ctx = newClassPathXmlApplicationContext"applicationContext.xml");BookDao bookDao = BookDao) ctx.getBean"bookDao");System.out.printlnbookDao);//按类型获取beanBookService bookService = ctx.getBeanBookService.class);System.out.printlnbookService);}
}
纯注解开发模式
配置文件applicationContext.xml删除掉,使用类来替换
实现步骤
- 创建配置类SpringConfig
public class SpringConfig {
}
- 标识该类为配置类
在配置类上添加@Configuration
注解,将其标识为一个配置类,替换applicationContext.xml
@Configuration
public class SpringConfig {
}
- 用注解替换包扫描配置
在配置类上添加包扫描注解@ComponentScan
替换<context:component-scan base-package=""/>
@Configuration
@ComponentScan"com.itheima")
public class SpringConfig {
}
- 创建一个新的运行类AppForAnnotation并运行
public class AppForAnnotation {public static void mainString[] args) {ApplicationContext ctx = newAnnotationConfigApplicationContextSpringConfig.class);BookDao bookDao = BookDao) ctx.getBean"bookDao");System.out.printlnbookDao);BookService bookService = ctx.getBeanBookService.class);System.out.printlnbookService);}
}
读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext"applicationContext.xml");
//加载配置类初始化容器
ApplicationContext ctx = new
AnnotationConfigApplicationContextSpringConfig.class);
注解开发Bean作用范围与生命周期管理
要想将BookDaoImpl变成非单例,只需要在其类上添加@scope注解
@Repository
//@Scope设置bean的作用范围
@Scope"prototype")
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ...");}
}
在BookDaoImpl中添加两个方法,init和destroy ,方法名可以任意
对方法进行标识,初始化方法和销毁方法
只需要在对应的方法上添加@PostConstruct和@PreDestroy注解即可
@Repository
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ...");}@PostConstruct //在构造方法之后执行,替换 init-methodpublic void init) {System.out.println"init ...");}@PreDestroy //在销毁方法之前执行,替换 destroy-methodpublic void destroy) {System.out.println"destroy ...");}
}
注意:@PostConstruct和@PreDestroy注解如果找不到,需要导入下面的jar包
<dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version>
</dependency>
注解开发依赖注入
注解实现按照类型注入
在BookServiceImpl类的bookDao属性上添加@Autowired
注解
@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;// public void setBookDaoBookDao bookDao) {// this.bookDao = bookDao;// }public void save) {System.out.println"book service save ...");bookDao.save);}
}
@Autowired
可以写在属性上,也可也写在setter方法上,最简单的处理方式是写在属性上并将setter方法删除掉
为什么setter方法可以删除呢?
- 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
- 普通反射只能获取public修饰的内容
- 暴力反射除了获取public修饰的内容还可以获取private修改的内容
- 所以此处无需提供setter方法
@Autowired是按照类型注入,那么对应BookDao接口如果有多个实现类,比如添加BookDaoImpl2
@Repository
public class BookDaoImpl2 implements BookDao {public void save) {System.out.println"book dao save ...2");}
}
这时候运行就会报错
此时,按照类型注入就无法区分到底注入哪个对象;解决方案:按照名称注入
先给两个Dao类分别起个名称
@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 save ...2" );}
}
- @Autowired是按照类型注入的,给BookDao的两个实现起了名称,它还是有两个bean对象
- @Autowired默认按照类型自动装配,如果IOC容器中同类的Bean找到多个,就按照变量名和Bean的名称匹配。因为变量名叫bookDao而容器中也有一个bookDao,所以可以成功注入。
- 如果按名称匹配,变量名为bookDao,而容器名为bookDao1和bookDao2,则不能成功注入,找不到容器
注解实现按照名称注入
当根据类型在容器中找到多个bean,注入参数的属性名又和容器中bean的名称不一致,就需要使用到@Qualifier来指定注入哪个名称的bean对象。
@Service
public class BookServiceImpl implements BookService {@Autowired@Qualifier"bookDao1")private BookDao bookDao;public void save) {System.out.println"book service save ...");bookDao.save);}
}
@Qualifier注解后的值就是需要注入的bean的名称。
注意:@Qualifier不能独立使用,必须和@Autowired一起使用
简单数据类型注入
简单类型注入的是基本数据类型或者字符串类型
使用@Value注解,将值写入注解的参数中就行了
@Repository"bookDao")
public class BookDaoImpl implements BookDao {@Value"itheima")private String name;public void save) {System.out.println"book dao save ..." + name);}
}
注解读取properties配置文件
@Value一般会被用在从properties配置文件中读取内容进行使用
- resource下准备properties文件
jdbc.properties
name=itheima888
- 使用注解加载properties配置文件
在配置类上添加@PropertySource注解
@Configuration
@ComponentScan"com.itheima")
@PropertySource"jdbc.properties")
public class SpringConfig {
}
- 使用@Value读取配置文件中的内容
@Repository"bookDao")
public class BookDaoImpl implements BookDao {@Value"${name}")private String name;public void save) {System.out.println"book dao save ..." + name);}
}
如果读取的properties配置文件有多个,可以使用@PropertySource的属性来指定多个
@PropertySource{"jdbc.properties","xxx.properties"})
IOC/DI注解开发管理第三方bean
环境准备
创建Maven项目
pom.xml添加Spring依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
</dependencies>
添加一个配置类SpringConfig
@Configuration
public class SpringConfig {
}
添加BookDao、BookDaoImpl类
public interface BookDao {public void save);
}
@Repository
public class BookDaoImpl implements BookDao {public void save) {System.out.println"book dao save ..." );}
}
创建运行类App
public class App {public static void mainString[] args) {AnnotationConfigApplicationContext ctx = newAnnotationConfigApplicationContextSpringConfig.class);}
}
注解开发管理第三方bean
在上述环境中完成对Druid数据源的管理,具体的实现步骤为:
- 导入对应的jar包
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
</dependency>
- 在配置类中添加一个方法,该方法的返回值就是要创建的Bean对象类型
@Configuration
public class SpringConfig {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;}
}
- 在方法上添加@Bean注解
@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象
@Configuration
public class SpringConfig {@Beanpublic 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;}
}
- 从IOC容器中获取对象并打印
public class App {public static void mainString[] args) {AnnotationConfigApplicationContext ctx = newAnnotationConfigApplicationContextSpringConfig.class);DataSource dataSource = ctx.getBeanDataSource.class);System.out.printlndataSource);}
}
引入外部配置类
public class JdbcConfig {@Beanpublic 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;}
}
使用包扫描引入
- 在Spring的配置类上添加包扫描
@Configuration
@ComponentScan"com.itheima.config")
public class SpringConfig {
}
- 在JdbcConfig上添加配置注解
JdbcConfig类要放入到com.itheima.config包下,需要被Spring的配置类扫描到即可
@Configuration
public class JdbcConfig {@Beanpublic 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;}
}
- 运行程序
这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,所有这种方式不推荐使用。
使用@Import
引入
必须在Spring配置类上使用@Import注解手动引入需要加载的配置类
- 去除JdbcConfig类上的注解
- 在Spring配置类中引入
@Configuration
//@ComponentScan"com.itheima.config")
@ImportJdbcConfig.class)
@ImportXxx.class)
public class SpringConfig {
}
注解开发实现为第三方bean注入资源
简单数据类型
— 持续更新中—
查看全文
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dgrt.cn/a/2243970.html
如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!
相关文章:
SSM_Spring
文章目录Spring系统架构Spring核心概念目前项目中的问题IOC控制反转DI(Dependency Injection)依赖注入Spring入门案例IOC入门案例DI入门案例IOC相关内容bean基础配置id与classname属性bean作用范围scope配置bean实例化环境准备构造方法实例化静态工厂实例……
【华为OD机试真题】打印机队列(javapython)
打印文件
时间限制:1s 空间限制:256MB限定语言:不限
题目描述:
有5台打印机打印文件,每台打印机有自己的待打印队列” 因为打印的文件内容有 轻重缓急之分,所以队列中的文件有1~10不同的优先级,其中数字越大优先级越 高。打印机会从自己的待打印队列中选择优先级最高的文件来……
【Java开发】设计模式 11:享元模式
1 享元模式介绍
享元模式是一种结构型设计模式,是一种对象池技术,它将多个小对象存储在一起,以节省内存。
享元模式的主要思想是共享可共享的对象,避免创建大量重复的对象,从而减少内存的使用。通过维护一个对象池&a……
webase全家桶搭建教程过程记录+bug解决
前置条件
Ubuntu20 基础环境搭建
检查Java
java -version
检查mysql(Ubuntu部署MySQL)
mysql –version 在装MySQL的时候发现了一个问题
就是不管怎么sudo mysql_secure_installation,,第二步设置密码就是不对,解……
对Javascript中作用域的理解?
一、作用域
作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合
换句话说,作用域决定了代码区块中变量和其他资源的可见性
举个例子
function myFunction) {let inVariable "……
Python 进阶指南(编程轻松进阶):五、发现代码异味
原文:http://inventwithpython.com/beyond/chapter5.html 导致程序崩溃的代码显然是错误的,但是崩溃并不是发现程序问题的唯一手段。其他迹象可能表明程序存在更微妙的错误或不可读的代码。就像气体的味道可以指示气体泄漏或者烟雾的味道可以指示火灾一样……
English Learning – L2 语音作业打卡 复习双元音 [eɪ] [aɪ] r 谦让型爆破技巧 Day46 2023.4.7 周五
English Learning – L2 语音作业打卡 复习双元音 [eɪ] [aɪ] r 谦让型爆破技巧 Day46 2023.4.7 周五💌发音小贴士:💌当日目标音发音规则/技巧:[eɪ][aɪ]谦让型爆破🍭 Part 1【热身练习】🍭 Part2【练习内容】&#x……
大数据任务调度器 —— Azkaban 3.0 部署与简单应用
什么是 Azkaban ?
Azkaban 是一个分布式的 工作流程管理器 Workflow Manager,在 LinkedIn 实现,用于解决 Hadoop 作业依赖问题,处理需要按顺序运行的作业,从 ETL 作业到数据分析产品。
Azkaban 的架构
Azkaban 的架构由 3 个核……
C语言——文件操作1)
本章重点 1. 为什么使用文件 2. 什么是文件 3. 文件的打开和关闭 4. 文件的顺序读写 5. 文件的随机读写 6. 文本文件和二进制文件 7. 文件读取结束的判定 8. 文件缓冲区 1.为什么使用文件
我们前面学习结构体时,写了通讯录的程序,当通讯录运行起来的时候……
windows下配置g2o+vs2013
整了两天,发现就这篇博客靠谱,当然其中也存在各种没注意的小bug
https://blog.csdn.net/xiaopihai1993/article/details/76644656
注意点:1、Eigen的版本不要太高,按照博主的版本eigen3.0.5就没问题,自己采用eigen3.……
杭州旭航集团,申请纳斯达克IPO上市,募资9800万美元
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,为中国企业提供数字内容营销服务的杭州旭航网络科技有限公司的控股公司Xuhang Holdings Ltd以下简称:旭航集团),近期已向美国证券交易委员会(SEC)提……
深度学习快速参考:11~13
原文:Deep Learning Quick Reference 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心如何实现目……
基于copula的风光联合场景生成与缩减
目录
1 主要内容
风光出力场景生成方法
2 部分程序
3 程序结果
4 程序链接
点击直达! 1 主要内容
该程序方法复现《融合风光出力场景生成的多能互补微网系统优化配置》风光出力场景生成部分,目前大多数研究的是不计风光出力之间的相关性影响&……
TS 使用自动提示生成对象中的键
TS 使用自动提示生成对象中的键
使用 plain object 而不是 class 的原因主要是在于 redux 中保存的对象需要为可序列化的对象。当然,具体操实现的时候肯定是可以无视这个需求的,不过 Redux 团队强烈建议使用可序列化对象,具体的官方文档说明……
Spring Boot概述(一)
1. SpringBoot 概述
1.1 SpringBoot 概念
SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的……
计算机笔试/面试常见逻辑题/智力题汇总
说明:按种类汇总,难度不分先后,做了分级罗列,方便后续扩充,大家有比较有意思的题目可以在讨论区讨论。 下面有的题题解相对复杂的直接参考了网上的一些解答,而有的题解我认为并不好的也做了补充,……
OpenAI文档翻译——搭建第一个自己的ChatGPT应用
这篇主要是讲了重头到位创建一个基于OpenAI API的应用程序的过程,同时给出了Node.js、Python版本的实例代码。应用程序的构建总体来说是很简单的就是一个接口调用,前提是我们需要提供密匙。
如果想要获取更好的结果返回一个是可以给模型提供一些列子从而……
python以及PyCharm工具的环境安装与配置
这里以Windows为例
Python的安装
当然是到Python官网下载咯,https://www.python.org/downloads/点我直达,如图: 可以下载最新版本,可以下拉找到之前特定的版本安装,如图: 这里先择的是最新版的进行安装……
JavaScript【六】JavaScript中的字符串String)
文章目录🌟前言🌟字符串String)🌟单引号和双引号的区别🌟属性🌟 length :字符串的长度🌟 方法🌟 str.charAtindex);🌟 str.charCodeAtindex);🌟 String.fromCharCode……
获取文件MD5小案例(未拆分文件)
文章目录前端获取MD5后端获取MD5前端获取MD5
1、引入js
<script src"js/spark-md5.min.js" type"text/javascript"></script>注:spark-md5库GitHub链接 2、这里是一个按钮和被隐藏调的<input/>标签 <body><button……
编程日记2023/4/16 14:57:19