本文最后更新于49 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1、容器
(1)创建容器
//容器初始化
//1.加载类路径下的配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从文件系统下加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");
//3.加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");
//获取bean
//使用bean名称获取
BookDao bookDao =(BookDao)ctx.getBean("bookDao");
//使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
//使用bean类型获取
BookDao bookDao = ctx.getBean(BookDao.class);
(2)容器类层次结构图
2、注解开发定义bean
- Spring提供@Component注解的三个衍生注解
- @Controller:用于表现层bean定义;
- @Service:用于业务层bean定义;
- @Repository:用于数据层bean定义。
功能一样,方便理解。
@Component("bookDao") //可以指定名称
public class BookDaoImpl implements BookDao{
}
@Component //不指定名称需要另配置
public class BookServiceImpl implements BookService {
}
//扫描bean加载
<context:component-scanbase-package="com.itheima"/>
3、纯注解开发模式
- 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
4、注解开发
(1)注解开发bean作用范围与生命周期管理
//作用范围
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao{
}
//生命周期
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao{
public BookDaoImpl(){
System.out.println("book dao constructor");
}
@PostConstruct
public void init(){
System.out.println("book init...");
}
@PreDestroy
public void destroy(){
System.out.println("book destory...");
}
}
(2)注解开发依赖注入
//使用@Autowired注解开启自动装配模式(按类型)
@Service
public class BookServiceImpl implements BookService{
@Autowired
private BookDao bookDao;
public void setBookDao(BookDao bookDao){
this.bookDao = bookDao;
}
public void save(){
System.out.println("book service save ..")
bookDao.save();
}
}
- 注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法;
- 注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法。
1)使用@Value实现简单类型注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao{
@Value("100")
private String connection Num;
}
2)使用@PropertySource注解加载properties文件
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
}
- 注意:路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*
(3)注解开发管理第三方bean
//使用@Bean配置第三方bean
@Configuration
public class SpringConfigr{
@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;
}
}
//建议使用独立的配置类管理第三方bean,写在一个JdbcConfig类中
//将独立的配置类加入核心配置
//方式一:导入式
//使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式
@Configuration
@Import(JdbcConfig.class)
public class SpringConfig{
}
//方式二:扫描式
//使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息
@Configuration
@ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"})
public class SpringConfig {
//不建议,易忘
}
(4)注解开发实现为第三方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 Stringg userName;
@Value("root")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(userName);
return ds;
}
}
//引用类型依赖注入
//引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象
@Bean
public DataSource dataSource(BookService bookService){
System.out.println(bookService);
DruidDataSource ds = new DruidDataSource();
//属性设置
return ds;
}
5、Spring整合
(1)整合mybatis
(2)整合Junit
//依赖导入
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
//例子
//设定类运行器,该注解告诉JUnit使用Spring的测试运行器来运行测试,而不是默认的JUnit运行器
@RunWith(SpringJUnit4ClassRunner.class)
//告诉测试框架使用SpringConfig类来配置应用程序上下文。SpringConfig类通常是一个带有 @Configuration 注解的 Java 配置类,它使用@Bean注解来声明 Spring容器中的bean
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testFindById() {
System.out.println(accountService.findById(1));
}
}
6、AOP
- AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构
- OOP(object Oriented Programming)面向对象编程。
- 作用:在不改代码为其进行功能增强。
- Spring理念:无入侵式/无侵入式
- 连接点(JoinPoint):原始方法的一个小功能的执行。
- 切入点(Pointcut):被加了功能的方法
- 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
- 一个具体方法:com.itheima.dao包下的BookDao接口中的无形参无返回值的save方法
- 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法
- 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
- 通知(Advice):在切入点处执行的操作,也就是共性功能
- 在SpringAOP中,功能最终以方法的形式呈现
- 通知类:定义通知的类
- 切面(Aspect):描述通知与切入点的对应关系
(1)案例
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
- 说明:切入点定义依托一个不具有实际意义的方法进行,即无参数,无返回值,方法体无实际逻辑
(2)AOP工作流程
- Spring容器启动
- 读取所有切面配置中的切入点
- 初始化bean,判定bean对应的类中的方法是否匹配到任意切入点
- 匹配失败,创建对象;
- 匹配成功,创建原始对象(目标对象)的代理对象。
- 获取bean执行方法
- 获取bean,调用方法并执行,完成操作。
- 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作。
- 目标对象(Target):原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的;
- 代理(Proxy):目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现
(3)AOP切入点表达式
7、Spring事务
事务作用:在数据层保障一系列的数据库操作原子性;
Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败。
(1)事务简介
//1、在业务层接口上添加Spring事务管理
//Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
//注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
public interface AccountService {
//配置当前接口方法具有事务
@Transactional
public void transfer(String out,String in ,Double money) ;
}
//2、设置事务管理器
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
//3、开启注解式事务驱动
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动,以后不管干什么,先开上。
@EnableTransactionManagement
public class SpringConfig {
}
(2)事务角色
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法;
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法
(3)事务属性
属性 | 作用 | 示例 |
---|---|---|
readOnly | 设置是否为只读事务 | readOnly=true 只读事务 |
timeout | 设置事务超时时间 | timeout = -1 (永不超时) |
rollbackFor | 设置事务回滚异常(class) | rollbackFor = {NullPointException.class} |
rollbackForClassName | 设置事务回滚异常(String) | 同上格式为字符串 |
noRollbackFor | 设置事务不回滚异常(class) | noRollbackFor = {NullPointException.class} |
noRollbackForClassName | 设置事务不回滚异常(String) | 同上格式为字符串 |
propagation | 设置事务传播行为 |
(3)事务传播行为
事务协调员对事务管理员所携带事务的处理态度。要不要加入事务?