一、Spring的Helloword

Spring归根到底就是帮助我们管理类和类的依赖关系
目的是为了降低类与类之间的依赖关系,进行组件之间的解耦
方便程序的扩展

  1. <bean id="car" class="com.class1.Car">
  2. <constructor-arg name="name" value="拖拉机"></constructor-arg>
  3. </bean>
  4. <bean id="user" class="com.class1.User">
  5. <constructor-arg name="username" value="曾帅阳"/>
  6. <constructor-arg name="passworld" value="123456"/>
  7. <constructor-arg name="car" ref="car"/>
  8. </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. 配置类中装配

  1. @Configuration 把本注解标注的类当成一个配置类,相当于一个xml文件
  2. @Bean 配置一个类,默认以方法名为bean的id,也可以通过name属性来指定id
  3. 直接通过方法调用来描述两个类之间的依赖关系。
  4. 混合配置: java配置引入xml配置(@ImportResource("classpath:app123.xml")
  5. @Import 加载另一个Java配置类

    3. 注解的方式装配

  6. @Controller、@Service、@Component、@Repository
    注解标注的类进行bean管理

  7. @ComponentScan

  • 扫描包及其子包,找上述四个注解,进行bean的管理
  • 扫描@Configuration注解,把该注解标注的类当成配置类


  1. @Autowired依赖注入,作用同@Resource
  2. @Value(“${name}”) 进行基本数据和String类型的属性的注入

    四、高级装配

  3. bean的作用域

    1. 单例
    2. 多例
  4. 运行时注入

占位符
el表达式

  1. 环境与profile

通过@Profile注解进行环境指定
image.png

  1. 条件化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面相切面編程
代码的复用
简化开发
方便扩展

关键术语

  1. 切面(Aspect)

共性的抽象,也可以理解为各个模块之间的共性代码

  1. 连接点(JoinPoint)

程序执行过程中某个特定的点,比如某方法调用的时候或者异常处理的时候,由于Spring只支持方法级别的连接点,所以在SpringAOP中的一个连接点总是表示一个方法

  1. 切入点(Pointcut)

切入点是匹配连接点的拦截规则,在满足这个切入点的连接点上运行通知,切入点表达式如何和连接点匹配是AOP的核心,Spring默认使用的是AspectJ切入点语法

  1. 通知(Advice)

在切面上拦截到某个特定的连接点之后执行的动作

  1. 目标对象

被一个或多个切面所通知的对象,即业务中需要增强的对象

  1. 织入(Weaving)

把切面作用到目标对象,产生代理对象的过程

关键代码

  1. 导包

    <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>
    
  2. 配置开启切面编程的注解

    @Configuration
    @EnableAspectJAutoProxy
    public class Config {
    }
    
  3. 定义切面

@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事务

什么是事务:

一段代码要么全部执行,要么全部不执行

事务的特性:

  1. 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
  2. 一致性(Consistemcy):不能破坏数据库的一致性状态。
  3. 隔离性(Isolation): 不同的事务之间互相不能影响。
  4. 持久性(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

七、SpringMVC快速入门