spring

91 阅读4分钟

IOC

DI 依赖注入

在bean中指定对应的依赖。 需要提供依赖对象对应的setter方法(容器去执行)

image.png

<bean id="bookservice" class="service">
<property name="bookDao" ref="bookDao"/>
</bean>

bean的配置

  • -基础配置 id class
  • 别名 name="xxx"
  • 作用范围 scope="" 默认为单例

spring实例化bean

方法一 调用bean的无参构造函数。(常用)
一般报错看倒数1,2行的报错。
方法二 使用静态工厂实例化bean 方法三 实例工厂(工厂不是静态) ![3DKNJFBLUDH~UPG]}I76@WE.png](p9-juejin.byteimg.com/tos-cn-i-k3…?)

方法四 使用FactoryBean实例化bean 使用getObject()创建对象

1653971128(1).png

1653971035(1).png

bean的生命周期

init-method="init" 初始化所有的函数 destory-method="destory" 销毁所用的函数

7bfc48e2b4d3e3cf967ffdbfa12395e.png

1653982200.png

setter依赖注入

1 引用类型

1653983180(1).png

1653983212(1).png

2 简单类型

1653983255(1).png

4951889e467254c2a40303826f97431.png

构造器注入(constructor-arg)

偶合度较高
1 引用类型 1653986018(1).png

1653986365(1).png

2 简单类型

a493726e9d62eebca5f40511e3839f6.png

1653986532(1).png

解决参数名称耦合问题

1653987236(1).png

依赖自动装配(只能对引用类型作用)

按类型

自动寻找set所需要的类型 按类型装配其实不需要id 1653988766(1).png

按名称

根据set函数的名称,来确定 setBookDao截取后的到bookDao为名字

1653988904(1).png

集合注入

数组 list set map Properties

1653989204(1).png

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <!--数组注入-->
    <property name="array">
        <array>
            <value>100</value>  //简单类型用value
            <value>200</value>
            <ref bean="beanId"/> //引用类型用ref
        </array>
    </property>
    <!--list集合注入-->
    <property name="list">
        <list>
            <value>itcast</value>
            <value>itheima</value>
        </list>
    </property>
    <!--set集合注入-->
    <property name="set">
        <set>
            <value>itcast</value>
            <value>itheima</value>
        </set>
    </property>
    <!--map集合注入-->
    <property name="map">
        <map>
            <entry key="country" value="china"/>
            <entry key="province" value="henan"/>
        </map>
    </property>
    <!--Properties注入-->
    <property name="properties">
        <props>
            <prop key="country">china</prop>
        </props>
    </property>
</bean>

加载properties文件

创建新的命名空间 1654068402(1).png

1654142005(1).png

1 开启context命名空间
2 使用context空间加载properties文件
3 使用属性占位符${}读取properties文件中的属性 1654069430(1).png 加载多个配置文件 <context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER> 所有的properties文件都加载 <context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER>

容器

1654142712(1).png

1654143628(1).png BeanFactory创建完毕后 所有bean均延迟加载

总结

容器

1654143911(1).png

bean

1654143953(1).png

依赖注入(向bean中注入数据)

1654144286(1).png

注解开发


<bean id="bookservice" class="service" init-method="init" destory-method="destory">

简化为下图 如果Component后不写内容则需要使用类型访问 1654146311(1).png

base-package 扫描这个目录下的所有文件 1654146453(1).png

规范化名称 1654146817(1).png

纯注解开发模式(spring3.0不应该有配置文件了)

目标:使用 代替配置文件 1654154067(1).png 初始化容器也发生了变化 1654154266(1).png

注解开法控制bean作用范围与生命周期

控制是否为单例 默认为单例 @Scope("prototype") 设置为非单例 生命周期 @PostConstruct构造方法后 @PerDestroy 彻底结束前

依赖注入

自动装配 @Autowired

引用类型

默认为按类型装配
想要按名称装配 想要在Component注解后加入名字 如Repository("bookDao1") 1654157652(1).png

简单类型

@Value("100")
private String name;

使用配置文件注入简单类型

配置类

@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource({"jdbc.properties"})
public class SpringConfig {
}

要注入的类

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    //@Value:注入简单类型(无需提供set方法)
    @Value("${name}")
    private String name;

    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

管理第三方bean

@bean

1654160268(1).png 但是都写在这里会导致SpringConfig太乱

使用导入方式管理bean

1654171585.png1654160911(1).png

为第三方bean 注入资源

简单类型

1654161409(1).png

引用类型

引用类型只需要给个形参 就会自动装配

@Bean
public DataSource dataSource(BookDao bookDao){
    System.out.println(bookDao);
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(userName);
    ds.setPassword(password);
    return ds;
}

Spring整合MyBatis

pom.xml

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.2.10.RELEASE</version>
</dependency>

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.3.0</version>
</dependency>

AOP简介 面向切面编程 (一种编程范式)

作用:在不惊动原始设计的基础上为其进行功能增强(不该源代码的情况下追加功能)
spring理念:无入侵编程 1654238961(1).png

a0eb3150677979fa856d683b98e7c02.png

AOP入门案例

1654240177(1).png 1 导入坐标

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.10.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.4</version>
</dependency>

2 制作连接方法,切面类 注意:切入点定义依托与一个不具有实际意义的方法进行,既无参数,无返回值,方法体无实际逻辑

//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
    //设置切入点,要求配置在方法上方
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}

    //设置在切入点pt()的前面运行当前操作(前置通知)
    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

3 在配置类中开启注解的aop编程

@Configuration
@ComponentScan("com.itheima")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}

AOP工作流程

1654244442(1).png

切入点表达式(控制给谁加)

@Pointcut("execution(....................)") 1654245618(1).png

cce999cd054f394b4af31529c156b14.png

AOP通知类型(控制往哪里加)

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}
    @Pointcut("execution(int com.itheima.dao.BookDao.select())")
    private void pt2(){}
    //@Before:前置通知,在原始方法运行之前执行
//    @Before("pt()")
    public void before() {
        System.out.println("before advice ...");
    }
    //@After:后置通知,在原始方法运行之后执行
//    @After("pt2()")
    public void after() {
        System.out.println("after advice ...");
    }
    //@Around:环绕通知,在原始方法运行的前后执行
//    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice ...");
        //表示对原始操作的调用
        Object ret = pjp.proceed();
        System.out.println("around after advice ...");
        return ret;
    }
//    @Around("pt2()")
    public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice ...");
        //表示对原始操作的调用
        Integer ret = (Integer) pjp.proceed();
        System.out.println("around after advice ...");
        return ret;
    }
    //@AfterReturning:返回后通知,在原始方法执行完毕后运行,且原始方法执行过程中未出现异常现象
//    @AfterReturning("pt2()")
    public void afterReturning() {
        System.out.println("afterReturning advice ...");
    }

    //@AfterThrowing:抛出异常后通知,在原始方法执行过程中出现异常后运行
    @AfterThrowing("pt2()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice ...");
    }
}

1654316378(1).png

image.png ProceedingJoinPoint类的方法

//获取执行的签名对象
Signature signature = pjp.getSignature();
//类型
String className = signature.getDeclaringTypeName();
//方法名
String methodName = signature.getName();

AOP通知获取数据

  • 获取参数
  • 获取返回值
  • 获取异常

获取参数

JoinPoint jp (如果通知方法参数中有他,则他必须在第一个位置)
jp.getArgs()
ProceedingJoinPoint pjp
pjp.getArgs()
作用:可以对参数进行处理 1654328684(1).png

获取返回值

image.png

获取异常

1654414041(1).png

spring事物

在数据层或者业务层保证一系列的数据库操作同成功同失败

1 一般@Transactional写在接口上不写在实现类上 写在AccountService上 1654418869(1).png

2 创建事物管理器

1654419142(1).png

3 在配置文件中声明事物

1654430992(1).png

Spring事物角色(spring如何实现事物)

将多个事物合并在一起,合并为一个到时候一起提交 e725af778253c8b96e394b0784bfe27.png

管理员:transfer 协调员:outMoney 1654432645(1).png

Spring事物属性

事物回滚

并不是所有异常都会使事物回滚 根据rollbackFor设置 1654434217(1).png

事物的传播行为(协调员对管理员的态度)

1654435252(1).png