Spring5
介绍:Spring 是一个轻量级[减少开发复杂度]的控制反转(IoC)和面向切面(AOP)的容器框架
依赖:
依赖介绍:
核心依赖
spring-core:Spring框架的核心组件,提供了Spring框架的基本组成部分,包括IoC和DI功能。 spring-beans:提供了BeanFactory,它是Spring框架的核心容器,用于管理应用程序中的对象。 spring-context:提供了Spring框架的上下文,包括应用程序的配置和生命周期管理。 spring-expression:提供了Spring框架的表达式语言,用于在运行时进行类型安全的计算。
面向切面编程
spring-aop:提供了Spring框架的AOP功能,用于在运行时进行面向切面的编程。
数据访问与集成
spring-jdbc:提供了Spring框架的JDBC支持,用于在应用程序中访问数据库。
spring-tx:提供了Spring框架的事务管理功能,用于在应用程序中管理事务。
web与远程访问
spring-web:提供了Spring框架的Web支持,包括MVC和RESTful Web服务。
spring-webmvc:提供了Spring框架的Web MVC支持,用于开发Web应用程序。
测试
spring-test
IOC(控制反转) -> 依赖注入(DI)
作用:解耦 -> 降低对象之间的耦合度 ->管理bean与bean之间的关系
原理(xml解析,工厂模式,反射)
接口
BeanFactory:创建和管理应用程序中的对象,也称为bean
ApplicationContext(应用程序上下文):是BeanFactory的一个扩展,可以通过XML配置文件、注解或Java代码来定义和配置bean
bean管理
bean生命周期
1.通过构造器创建bean实例(无参构造)
2.为bean的属性设置值和对其他的bean引用(调用set方法)
3.调用bean的初始化方法(查看:<bean init-method>)
4.使用bean
5.当容器关闭时候,调用bean的销毁方法(查看:<bean distror-method>)
bean作用域
单例(Singleton):在整个应用中,只创建一次bean实例
原型(Prototype):每次注入或者通过上下文获取bean时候,都会创建一个新的bean实例
请求(Request):在Web应用中,为每个请求创建一个bean实例
会话(Session):在Web应用中,为每个会话创建一个bean实例
基于XML:<bean id="" class="类全路径" scope="prototype"/> 基于注解:@Scope("prototype")
应用(xml)
set注入
Student student = new Student(); student.setId(1);
注入的数据类型
数组
<property name="set"> <set> <value>和平精英</value> </set> </property>
list
<property name="list"> <list> <value>张三</value> </list> </property>
map
<property name="map"> <map> <entry key="user1" value-ref="user1"></entry> </map> </property>
set
<property name="set"> <set> <value>和平精英</value> </set> </property>
properties
<property name="properties"> <props> <prop key="p1">悟空</prop> </props> </property>
空值注入
<property name=""></null></property>
特殊符号注入
<property name=""> <value> <![CDATA[ <<aa>> ]]> //值 <<aa>> </value> </property>
级联注入
<property name="props"> <bean id="" class="关联对象全路径"> <property name="" value=""></property> </bean> </property> <property name="props" ref="a"></property> <property name="a.b" value=""></property> //获取关联对象的某一个值,需对该对象设置get方法 <bean id="a" class="关联对象全路径"> <property name="b" value=""></property> </bean>
构造注入
<constructor-arg index="0" value="User的有参构造"/> //下标赋值 <constructor-arg type="java.lang.String" value="User有参构造"></constructor-arg> //类型创建 <constructor-arg name="name" value="唐昊"></constructor-arg> //参数名
注入外部bean
使用
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml"); //User user = context.getBean("user", User.class); User user = (User)context.getBean("user");
注解注入
<!--开启注解扫描-->
<context:component-scan base-package="注解所在包/类路径"/>
1. @Autowired , @Qualifier("") -> 名称注入
2. @Resource -> @Resource(neme="") ->名称注入
3. @Value(value="")
AOP(面向切面编程)
概念:将公有方法抽取到一个类中再通过代理方式获取
通知(增强方法)
切入点表达式
execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
execution(* com.kuang.service.UserServiceImpl.*(..))
自定义切面类
xml
<!-- 方式二:自定义类--> <bean id="diy" class="com.kuang.diy.DiyPointCut"/> <aop:config> <!-- 自定义切面,ref要引用的类--> <aop:aspect ref="diy"> <!--切入点 --> <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--通知 --> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
注解
<!--开启Aspectj生成代理对象 --> <aop:aspectj-autoproxy/>
@Component @Aspect @Order(3) //通知级别 public class StudenAspect { @Pointcut("execution(* com.xinyu.service.impl.StudentServiceImpl.*(..))") public void pointcut() { } @Before("pointcut()") public void before(){ System.out.println("before..."); } @After("pointcut()") public void after(){ System.out.println("after..."); } @AfterReturning("pointcut()") public void afterReturning(){ System.out.println("afterReturning..."); } @AfterThrowing(value = "pointcut()",throwing = "ex") public void afterThrowing(Exception ex){ System.out.println("afterThrowing..."+ex.getMessage()); } @Around("pointcut()") public Object around(ProceedingJoinPoint jp) throws Throwable { System.out.println("aroundBefore..."); Object obj = jp.proceed(); System.out.println("aroundAfter..."); return obj; } }
事务管理
特性
原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成
一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失
隔离性(Isolation):指多个事务并发访问数据库时,每个事务都应该感觉不到其他事务的存在,即每个事务的内部操作与其他事务的内部操作相互隔离
// 1. READ_UNCOMMITTED(读未提交):一个事务可以读取另一个事务未提交的数据,可能导致脏读、不可重复读和幻读问题。 // 2. READ_COMMITTED(读已提交):一个事务只能读取另一个事务已经提交的数据,可以避免脏读问题,但是可能导致不可重复读和幻读问题。 // 3. REPEATABLE_READ(可重复读):一个事务在执行期间多次读取同一数据,保证在事务执行期间多次读取的结果是一致的,可以避免脏读和不可重复读问题,但是可能导致幻读问题。 // 4. SERIALIZABLE(串行化):最高的隔离级别,强制事务串行执行,可以避免脏读、不可重复读和幻读问题,但是会影响并发性能。
脏读(Dirty Read)指一个事务读取了另一个事务未提交的数据,如果另一个事务回滚,则当前事务读取的数据是无效的。 不可重复读(Non-repeatable Read)指一个事务在执行过程中多次读取同一数据,但是由于其他事务的修改,每次读取的结果都不同。 幻读(Phantom Read)指一个事务在执行过程中多次查询同一范围的数据,但是由于其他事务的插入或删除,每次查询的结果集都不同。
<!-- 事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 事务管理器注解(让@Transactional生效)--> <tx:annotation-driven transaction-manager="transactionManager"/>
单元测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring.xml"})
@MapperScan("com.xinyu.dao")
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); SysLogService sysLogService = context.getBean("syslogService",SysLogService.class);
spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!--开启注解扫描--> <context:component-scan base-package="com.xinyu"/> <!--生成切面对象--> <aop:aspectj-autoproxy/> <!--连接数据库--> <!--1.导入外部文件--> <context:property-placeholder location="classpath*:mysql.properties"/> <!--2.配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="url" value="${jdbc.url}"/> <property name="testWhileIdle" value="true"/> </bean> <!-- 配置SqlSessionFactory对象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 注入数据库连接池 --> <property name="dataSource" ref="dataSource"/> <!-- 配置MyBaties全局配置文件:mybatis.xml --> <property name="configLocation" value="classpath:mybatis.xml"/> </bean> <!-- 配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 注入sqlSessionFactory --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- mapper --> <property name="basePackage" value="com.xinyu.dao"/> </bean> <!-- 事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 事务管理器注解(让@Transactional生效)--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--注入status实体--> <bean id="status" class="com.xinyu.entity.Status"/> </beans>