一、Spring的Helloword
Spring归根到底就是帮助我们管理类和类的依赖关系
目的是为了降低类与类之间的依赖关系,进行组件之间的解耦
方便程序的扩展
<bean id="car" class="com.class1.Car">
<constructor-arg name="name" value="拖拉机"></constructor-arg>
</bean>
<bean id="user" class="com.class1.User">
<constructor-arg name="username" value="曾帅阳"/>
<constructor-arg name="passworld" value="123456"/>
<constructor-arg name="car" ref="car"/>
</bean>
//告诉我们spring让spring来管理我们类
//Spring容器
ApplicationContext app
= new ClassPathXmlApplicationContext("app.xml");
User user1 = app.getBean("user", User.class);
System.out.println(user1);
二、IOC/DI的概念
IOC( Inversion of controll) 控制反转:
对象的创建和赋值和依赖管理等等由自己控制转向由容器控制
DI( dependence injection)依赖注入
管理对象的依赖关系(构造器注入,setter注入)
三、装配一个bean
1. xml装配
id: 指定bean在容器中的唯一值
class: 指定要管理的那个bean的全类名
scope:指定作用域,
- singleton(单例),
- prototype(多例),每次获取bean,容器都给我们new一个新的对象
- session
- request
primary:如果有相同类型的bean存在,优先取primary标注的那个bean
init-method:初始化类的时候调用
detory-method: 回收的时候调用
lazy-init:默认false,容器启动时,实例化所有的bean
注入:
(属性赋值:)
setter注入:
构造注入:
共同的属性:
name
value: 赋值基本数据类型和String类型
ref: 引用,赋值类类型的引用
2. 配置类中装配
- @Configuration 把本注解标注的类当成一个配置类,相当于一个xml文件
- @Bean 配置一个类,默认以方法名为bean的id,也可以通过name属性来指定id
- 直接通过方法调用来描述两个类之间的依赖关系。
- 混合配置: java配置引入xml配置(
@ImportResource("classpath:app123.xml")
) - @Import 加载另一个Java配置类
3. 注解的方式装配
@Controller、@Service、@Component、@Repository
注解标注的类进行bean管理@ComponentScan
- 扫描包及其子包,找上述四个注解,进行bean的管理
- 扫描@Configuration注解,把该注解标注的类当成配置类
占位符
el表达式
- 环境与profile
通过@Profile注解进行环境指定
- 条件化bean
@Conditional
Condition接口
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
try {
//读取properties文件
String path = "E:\\developer\\JAVA\\workspace\\study-spring\\conditional\\src\\main\\resources\\config.properties";
Properties properties = new Properties();
FileInputStream is = new FileInputStream(path);
properties.load(is);
String config = properties.getProperty("config");
if ("true".equals(config)) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
五、AOP编程
基本概念
Aspect Oriented Programming面相切面編程
代码的复用
简化开发
方便扩展
关键术语
- 切面(Aspect)
共性的抽象,也可以理解为各个模块之间的共性代码
- 连接点(JoinPoint)
程序执行过程中某个特定的点,比如某方法调用的时候或者异常处理的时候,由于Spring只支持方法级别的连接点,所以在SpringAOP中的一个连接点总是表示一个方法
- 切入点(Pointcut)
切入点是匹配连接点的拦截规则,在满足这个切入点的连接点上运行通知,切入点表达式如何和连接点匹配是AOP的核心,Spring默认使用的是AspectJ切入点语法
- 通知(Advice)
在切面上拦截到某个特定的连接点之后执行的动作
- 目标对象
被一个或多个切面所通知的对象,即业务中需要增强的对象
- 织入(Weaving)
把切面作用到目标对象,产生代理对象的过程
关键代码
导包
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
配置开启切面编程的注解
@Configuration @EnableAspectJAutoProxy public class Config { }
定义切面
@Aspect注解标明本类是一个切面类
@Pointcut 定义切点(往哪切)
@Before(“performance()”) 前置通知
@After(“performance()”) 后置通知
@Around(“performance()”) 环绕通知
@Aspect
@Component //交付给spring管理
public class Audience {
@Pointcut("execution(* class1.aop.UserService.getUser(..))") //切点
public void performance() {}
@Before("performance()")
public void m1() {
System.out.println("before");
}
@After("performance()")
public void m2() {
System.out.println("after");
}
@Around("performance()")
public void m3(ProceedingJoinPoint jp) throws Throwable {
System.out.println("arroud before");
jp.proceed();
System.out.println("arroud after");
}
}
底层实现(面试题):
静态代理
动态代理
六、Spring事务
什么是事务:
事务的特性:
- 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
- 一致性(Consistemcy):不能破坏数据库的一致性状态。
- 隔离性(Isolation): 不同的事务之间互相不能影响。
- 持久性(Durability):事务提交以后,即保存数据,不会再回滚。
springboot整合mybatis
1、 导包
<!-- springboot整合mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
2、application.xml配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test_spring_trasaction?serverTimezone=UTC
spring.datasource.username=miao
spring.datasource.password=923713
3、 写一对mapper和xml
public interface AccountMapper extends Mapper {
int getMoneyByName(String name);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.class1.mapper.AccountMapper">
<select id="getMoneyByName" resultType="int" parameterType="string">
select money from accout where name=#{name};
</select>
</mapper>
4、标明mapper.xml和mapper接口的位置
mybatis.mapper-locations=classpath:mapper/*.xml
@MapperScan("com.class1.mapper")
Spring中使用事务
1、开启事务@EnableTransactionManagement
2、使用注解去标注方法@Transactional
Spring中事务的传播特性
REQUIRED(默认),
父方法有事务,子方法也会在同一个事务之下
父方法没有事务,子方法会自己创建一个事务
SUPPORTS,
父方法有事务,子方法也会在同一个事务之下
父方法没有事务,子方法也没有事务
MANDATORY,
REQUIRES_NEW,
父方法有事务,子方法会创建一个新的事务
父方法没有事务,子方法会自己创建一个事务
NOT_SUPPORTED
父方法有事务,子方法挂起父方法的事务
NEVER
NESTED