核心理念
与主流框架集成,不重复造轮子
核心特性
依赖注入(IOC)
核心思想
它是一种设计思想,将你设置好的对象交给容器控制,而不是显示地用代码进行对象的创建
对象由Spring来创建,管理,装配
实现方式
基础实现方式
导入相关jar包配置xml,其中javaBean必须加入get和set方法
一般实现方式
maven+注解+xml
定义bean
@Controller @Service @Repository @Component
注入
手动注入
@Value("liu"),亦可用${},#{}
自动注入
- @Autowire:依赖spring,默认优先根据类型去匹配,多个类型再按名字(属性名)查找,都没匹配到会报错
- @Resource:依赖jdk,默认优先根据名字匹配,在根据类型匹配,类型不存在或多个会报错
其他注解
@DependsOn
调整加载顺序
@Lazy
设置为懒加载,默认情况下不是懒加载哦。
@Scope
设置容器作用域,默认为单例,可设置为多例等。
生命周期
- @PostConstructor:初始化
- @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
- 它是一个方法级别的注解,他与xml中bean元素类似,支持对应属性
- 可用在@Configuration或@Component
- 可以通过name属性设置bean的名字(id)
- 自动依赖外部bean,直接在方法里面写上对应参数即可无需再加Autowired注解
- 自动依赖内部bean,直接调用对应方法即可
- 代替工厂方法生成bean
@PropertySource
例如:PropertySource("db.properties"),用来加载配置文件
@ComponentScan
包扫描
@Import
- 导入其他配置类
- 导入类注册为bean,只能类匹配
- 导入ImportSelector实现类,可以注册多个bean,只能类匹配
- 导入ImportBeanDefinitionRegistrar,可以注册多个bean定义
备注
- 默认bean:类名、属性名、方法名,采用小驼峰
- 注解value()可省略
面向切面编程(AOP)
用途
跟主要业务没关系的公共功能代码,不修改之前代码的情况下增强到写好的方法指定位置
原理
通过动态代理实现
注解
@Aspectj:声明为切面,还需要@Component注解将切面交给Spring管理
内容
通知
过程
- 正常过程:前置-方法-后置-返回
- 异常过程:前置-方法-后置-异常
类型
- 前置通知:在目标方法执行前执行
- 后置通知:在目标方法执行后执行(无论是否发生异常)执行,在返回通知前执行
- 后置返回通知:在目标方法正常返回后执行
- 后置异常通知:在目标方法抛出异常后执行
- 环绕通知:在目标方法执行前后都可执行,可以控制目标方法的执行
切入点表达式
- execution:细粒度
- within:粗粒度
- 合并切点表达式:&&,||,!
问题
被代理的类,通过具体类型能找到吗?
答:不能,aop拦截了,并把代理类存入IOC容器中,只能根据名字或接口获取
声明式事务(@Transactional)
可以标记在类或方法上,一般在业务逻辑层,service层,建议写在方法上
属性
- isolation:设置事务隔离级别
- propagation:事务传播行为
- noRollbackFor:哪些异常事务可以不回滚
- noRollbackForClassName:填写为全类名
- rollbackFor:哪些异常事务需要回滚,默认为RuntimeException和Error
- rollbackForClassName:填写为全类名
- readOnly:设置事务是否为只读事务,用在RR隔离级别
- timeout:事务超出指定时长自动终止并回滚,单位是秒