1.Spring Framework架构
- Core Container:核心容器
- AOP:面向切向编程
- Aspects:AOP思想实现
- Data Access:数据访问 Data Intergation:数据集成
- Web:Web开发
- Test:单元测试与集成测试
2.Spring Framework学习路线
3.核心概念
代码现状:耦合度偏高。
解决方案:使用对象时,在程序中不要主动使用new产生对象,转为由外部提供对象。
Ioc控制反转:对象的创建控制权由程序转移到外部(主动new对象转为由外部提供对象),这种思想称为控制反转。
Spring技术对IOC思想进行了实现:
Spring提供了一个容器,用来充当IoC思想中的“外部”。
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean。
DI依赖注入:在容器中建立Bean和Bean之间的依赖关系的整个过程称为Bean依赖
目标:充分解耦
使用IoC容器管理Bean。
在IoC容器内将有依赖关系的bean进行关系绑定(DI)
最终效果:使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系。
4.IoC入门案例(XML版本)
1.管理什么?(Service与Dao)
2.如何将被管理的对象告知IoC容器?(配置)
3.被管理的对象交给IoC容器,如何获取到IoC容器?(接口)
4.IoC容器得到后,如何从容器中获取Bean?(接口方法)
5.使用Spring导入哪些坐标?(pom.xml)
步骤:
1.导入Spring坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.21.RELEASE</version>
</dependency>
2.定义Spring管理的类(接口)
public interface BookService {
void save();
}
public class BookServiceImpl implements BookService {
BookDao bookDao = new BookDaoImpl();
@Override
public void save() {
bookDao.save();
}
}
3.创建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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 1.导入Spring坐标spring-context-->
<!-- 2.配置Bean-->
<!-- id属性表示给Bean起名字-->
<!-- class属性表示给Bean定义类型-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" />
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" />
</beans>
4.初始化容器,通过容器获得Bean
public class App {
public static void main(String[] args) {
//3.获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//4.获取Bean
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
5.DI入门案例
1.基于IoC管理Bean
2.Service中使用new形式创建Dao对象是否保留?(否)
3.Servcie中需要的Dao对象如何进入Service中?(提供方法)
4.Service与Dao间的关系如何描述?(配置)
步骤:
1.删除使用new的形式创建的代码
2.提供依赖对象对应的set方法
public class BookServiceImpl implements BookService {
//5.删除业务层中使用new方法创建的dao对象
BookDao bookDao;
@Override
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
//6.提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
3.配置Service与Dao的关系
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" >
<!-- 7.配置server与dao的关系-->
<!-- property标签表示配置当前Bean的属性-->
<!-- name属性表示配置哪一个具体的属性-->
<!-- ref属性表示参照哪一个Bean-->
<property name="bookDao" ref="bookDao"/>
6 bean基础配置
6.1 bean的别名配置(name属性)
6.2 bean的作用范围(scope属性)
适合交给容器管理的bean:
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合交给容器管理的bean:封装实体的域对象
7.bean实例化
7.1 Bean是如何创建的
1.构造方法实例化Bean(常用)
2.使用静态工厂实例化Bean
public class BookDaoFactory {
public static BookDao getBookDao(){
return new BookDaoImpl();
}
}
<bean id="bookDao2" class="com.itheima.factory.BookDaoFactory" factory-method="getBookDao" />
3.实例工厂初始化Bean
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
<bean id="userDaoFactory" class="com.itheima.factory.UserDaoFactory" />
<bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"/>
3-1 使用FactoryBean实例化Bean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
@Override
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
@Override
public Class<?> getObjectType() {
return UserDao.class;
}
}
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean" />
8.Bean的生命周期
初始化容器:
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set操作)
- 执行Bean初始化方法
使用Bean:执行业务操作
关闭/销毁容器:执行Bean销毁
方法一:配置生命周期控制方式
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("dao save ...");
}
public void init(){
System.out.println("bookdao init");
}
public void destory(){
System.out.println("bookdao destory");
}
}
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory" />
方法二:实现接口
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
//5.删除业务层中使用new方法创建的dao对象
BookDao bookDao;
@Override
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
//6.提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void destroy() throws Exception {
System.out.println("service destory");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
}
9.依赖注入方式
依赖注入方式:
- setter注入:简单类型、引用类型
- 构造器注入:简单类型、引用类型
9.1 setter注入简单类型:
public class BookDaoImpl implements BookDao {
private int ConnectionNum;
private String databaseName;
public void setConnectionNum(int connectionNum) {
ConnectionNum = connectionNum;
}
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
@Override
public void save() {
System.out.println("dao save ..."+ConnectionNum +" "+databaseName);
}
}
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<property name="connectionNum" value="10" />
<property name="databaseName" value="mysql"/>
</bean>
9.2 setter注入引用类型(见5 DI入门案例)
9.3 构造注入引用类型
public class UserDaoImpl implements UserDao {
private BookDao bookDao;
public UserDaoImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
public UserDaoImpl() {
}
@Override
public void save() {
System.out.println("userdao save ...");
}
}
<bean id="userDao2" class="com.itheima.dao.impl.UserDaoImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
9.4 构造注入普通类型
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg name="connectionNum" value="10"/>
<constructor-arg name="databaseName" value="hh"/>
</bean>
9.5 优化name属性造成的高耦合:index属性(使用位置来表示属性)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg index="0" value="10"/>
<constructor-arg index="1" value="hh"/>
</bean>
9.6 依赖注入选择
10.依赖自动装配
10.1 演示案例
byType自动装配,要求:
- 装配的类只能有一个Bean
- 必须要有Setter方法
public class PeopleImpl implements PeopleDao {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
System.out.println("PeopleDao is save...");
System.out.println("userDao已注入:"+userDao);
}
}
<bean id="peopleDao" class="com.itheima.dao.impl.PeopleImpl" autowire="byType"/>
10.2 依赖自动装配特征
- 自动装配用于引用类型依赖注入,不能对简单类型注入
- 使用按类型装配时(byType)必须保障容器中相同类型的Bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有制定名称的Bean,有耦合不建议使用
- 自动装配优先级低于setter注入和构造器注入,同时出现时自动装配失效
11.集合注入
public class HhImpl implements hhDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String ,String> map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println("HH dao save ...");
System.out.println("遍历数组:"+ Arrays.toString(array));
System.out.println("遍历List:"+ list);
System.out.println("遍历set:"+set);
System.out.println("遍历map"+map);
System.out.println("遍历Properties"+properties);
}
}
<bean id="hhDao" class="com.itheima.dao.impl.HhImpl">
<property name="array">
<array>
<value>1</value>
<value>1</value>
<value>3</value>
</array>
</property>
<property name="list">
<list>
<value>1</value>
<value>1</value>
<value>3</value>
</list>
</property>
<property name="set">
<set>
<value>1</value>
<value>1</value>
<value>3</value>
</set>
</property>
<property name="map">
<map>
<entry key="country" value="China"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<property name="properties">
<props>
<prop key="country">China</prop>
<prop key="province">hennan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
12.第三方资源配置管理
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc::mysql://localhost:3306/book" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
13 集合对象和properties文件的加载
13.1 集合对象
public class HhImpl implements hhDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String ,String> map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println("HH dao save ...");
System.out.println("遍历数组:"+ Arrays.toString(array));
System.out.println("遍历List:"+ list);
System.out.println("遍历set:"+set);
System.out.println("遍历map"+map);
System.out.println("遍历Properties"+properties);
}
}
<bean id="hhDao" class="com.itheima.dao.impl.HhImpl">
<property name="array">
<array>
<value>1</value>
<value>1</value>
<value>3</value>
</array>
</property>
<property name="list">
<list>
<value>1</value>
<value>1</value>
<value>3</value>
</list>
</property>
<property name="set">
<set>
<value>1</value>
<value>1</value>
<value>3</value>
</set>
</property>
<property name="map">
<map>
<entry key="country" value="China"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<property name="properties">
<props>
<prop key="country">China</prop>
<prop key="province">hennan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
13.2 properties文件的加载
<!-- 1.开启context命名空间-->
<?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 http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 2.使用context空间加载properties文件-->
<context:property-placeholder location="jdbc.properties" />
<!-- 3.使用属性占位符${}读取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>
如果要加载多个配置文件
14 容器
14.1 创建容器
加载配置文件的方法:
Bean加载的三种方式:
14.2 核心容器总结
1 容器相关:
2 Bean相关
3 依赖注入相关
15 注解开发定义Bean
三个衍生注解(本质与Component相同)
16 纯注解开发
17 Bean作用范围和生命周期的管理
singleton为单例,prototype为多例
18 依赖注入
18.1 Bean类型注入
18.2 简单类型注入
18.3 加载文件
19 第三方Bean管理
20.XML配置与注解配置对比
21 Spring整合MyBatis
21.1 导入依赖
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
21.2 MyBatis整合
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("com.itheima.domain");
ssfb.setDataSource(dataSource);
return ssfb;
}
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
22 AOP
22.1 AOP简介
22.2 AOP核心概念
23 AOP入门案例
23.1 导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
23.2 接口和类
public interface BookDao {
void save();
void update();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save(){
System.out.println(System.currentTimeMillis());
System.out.println("book dao save ...");
}
public void update(){
System.out.println("book dao update ...");
}
}
23.3 Spring执行程序
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookD = acac.getBean(BookDao.class);
bookD.update();
}
}
23.3 Spring配置类
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy //告诉Spring 是使用注解开发AOP
public class SpringConfig {
}
23.4 AOP实现
@Component //告诉spring需要被加载
@Aspect //告诉spring是用来做AOP服务的
public class MyAdvice {
@Pointcut("execution(void com.itheima.dao.BookDao.update())") //定义好切入点
public void pt(){
}
@Before("pt()") //将切入点和通知绑定
public void method(){ //定义通知
System.out.println(System.currentTimeMillis());
}
}