Spring基础,来温习一下~

97 阅读3分钟

核心理念

与主流框架集成,不重复造轮子

核心特性

依赖注入(IOC)

核心思想

它是一种设计思想,将你设置好的对象交给容器控制,而不是显示地用代码进行对象的创建

对象由Spring来创建,管理,装配

实现方式

基础实现方式

导入相关jar包配置xml,其中javaBean必须加入get和set方法

一般实现方式

maven+注解+xml

定义bean

@Controller @Service @Repository @Component

注入
手动注入

@Value("liu"),亦可用${},#{}

自动注入
  1. @Autowire:依赖spring,默认优先根据类型去匹配,多个类型再按名字(属性名)查找,都没匹配到会报错
  2. @Resource:依赖jdk,默认优先根据名字匹配,在根据类型匹配,类型不存在或多个会报错
其他注解
@DependsOn

调整加载顺序

@Lazy

设置为懒加载,默认情况下不是懒加载哦。

@Scope

设置容器作用域,默认为单例,可设置为多例等。

生命周期
  1. @PostConstructor:初始化
  2. @PreDestroy:销毁
配置
基础配置
<!--使用name设置多个别名-->
<bean class="com.example.maven.entity.User" id="user" name="user3;user4">
    <description>描述bean</description>
    <!--基于setter方法的依赖注入,注意基于方法名setXxx > xxx-->
    <property name="id" value="1"></property>
</bean>
<!--设置bean的别名-->
<alias name="user" alias="user2"></alias>
<!--可以导入其他xml-->
<!--<import resource="spring-ioc.xml"></import>-->

<bean class="com.example.maven.entity.User" id="user5">
    <description>描述bean</description>
    <!--基于构造函数,可以只有value按照自上而下顺序,也可以用index下标方式或type-->
    <constructor-arg name="id" value="1"></constructor-arg>
    <constructor-arg name="name" value="2"></constructor-arg>
</bean>
高级配置
<!--默认自上而下去加载,加上depends-on后会先加载on里边的-->
<bean class="com.example.maven.entity.Person" id="person" depends-on="wife"></bean>
<bean class="com.example.maven.entity.Wife" id="wife" primary="true">
    <property name="age" value="1"></property>
</bean>
<!--懒加载,只在使用时加载-->
<bean class="com.example.maven.entity.Person" id="person1" lazy-init="true"></bean>
<!--作用域,建议存在共享变量读写时最后改成多例,避免线程安全问题-->
<bean class="com.example.maven.entity.Person" id="person2" lazy-init="true" scope="prototype"></bean>
<!--使用静态工厂实例化bean-->
<bean class="com.example.maven.entity.Person" id="person3" factory-method="createPeasenFactory"></bean>
<!--使用非静态工厂实例化bean-->
<bean class="com.example.maven.entity.Person" id="person4" factory-bean="factory" factory-method="createPeasenFactory"></bean>
<bean class="com.example.maven.entity.PersonFactory" id="factory"></bean>
<!--自动注入-->
<bean class="com.example.maven.entity.Person" id="person5" autowire="byName"></bean>
<!--生命周期回调-->
<bean class="com.example.maven.entity.Person" id="person6" init-method="initByConfig" destroy-method="destroyByConfig"></bean>
<!--三方-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    <property name="username" value="${mysql.username}"></property>
    <property name="password" value="123456"></property>
    <property name="url" value=""></property>
    <property name="driverClassName" value=""></property>
</bean>
<!--引入外部属性配置文件-->
<context:property-placeholder location="dp.properties"></context:property-placeholder>
<!--SpEl spring表达式-->
<bean class="com.example.maven.entity.Person" id="person7">
    <!--运算表达式 id为3-->
    <property name="id" value="#{1+2}"></property>
    <property name="wife" value="#{wife}"></property>
    <property name="name" value="#{wife.name}"></property>
    <property name="gender" value="#{wife.getAge()}"></property>
    <property name="birthday" value="#{T(com.example.maven.entity.PersonFactory).getNewDate()}"></property>
</bean>

好的实现方式

springboot+javaconfig

常用注解
@Configuration

标注配置类

@Bean
  1. 它是一个方法级别的注解,他与xml中bean元素类似,支持对应属性
  2. 可用在@Configuration或@Component
  3. 可以通过name属性设置bean的名字(id)
  4. 自动依赖外部bean,直接在方法里面写上对应参数即可无需再加Autowired注解
  5. 自动依赖内部bean,直接调用对应方法即可
  6. 代替工厂方法生成bean
@PropertySource

例如:PropertySource("db.properties"),用来加载配置文件

@ComponentScan

包扫描

@Import
  1. 导入其他配置类
  2. 导入类注册为bean,只能类匹配
  3. 导入ImportSelector实现类,可以注册多个bean,只能类匹配
  4. 导入ImportBeanDefinitionRegistrar,可以注册多个bean定义
备注
  1. 默认bean:类名、属性名、方法名,采用小驼峰
  2. 注解value()可省略

面向切面编程(AOP)

用途

跟主要业务没关系的公共功能代码,不修改之前代码的情况下增强到写好的方法指定位置

原理

通过动态代理实现

注解

@Aspectj:声明为切面,还需要@Component注解将切面交给Spring管理

内容

通知

过程
  • 正常过程:前置-方法-后置-返回
  • 异常过程:前置-方法-后置-异常
类型
  • 前置通知:在目标方法执行前执行
  • 后置通知:在目标方法执行后执行(无论是否发生异常)执行,在返回通知前执行
  • 后置返回通知:在目标方法正常返回后执行
  • 后置异常通知:在目标方法抛出异常后执行
  • 环绕通知:在目标方法执行前后都可执行,可以控制目标方法的执行

切入点表达式

  • execution:细粒度
  • within:粗粒度
  • 合并切点表达式:&&,||,!

问题

被代理的类,通过具体类型能找到吗?

答:不能,aop拦截了,并把代理类存入IOC容器中,只能根据名字或接口获取

声明式事务(@Transactional)

可以标记在类或方法上,一般在业务逻辑层,service层,建议写在方法上

属性

  • isolation:设置事务隔离级别
  • propagation:事务传播行为
  • noRollbackFor:哪些异常事务可以不回滚
  • noRollbackForClassName:填写为全类名
  • rollbackFor:哪些异常事务需要回滚,默认为RuntimeException和Error
  • rollbackForClassName:填写为全类名
  • readOnly:设置事务是否为只读事务,用在RR隔离级别
  • timeout:事务超出指定时长自动终止并回滚,单位是秒

事务传播特性

image.png