Spring
spring开源的、轻量级、非入侵式的框架;支持事务处理、支持框架整合
主要思想:IOC(控制反转)、AOP(面向切面编程)
spring4大模块
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHn8BdzJ-1595243404386)(D:\word\typoraImages\image-20200720124817404.png)]
1. Data Access/Integration(数据访问/集成)
- JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
- ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
- OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
- JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
- Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。
2. Web 模块
- Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
- Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
- Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
- Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。
3. Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础
- Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
- Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
- Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
- Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。
4. 其他模块
- AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
- Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
- Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
- Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。
IOC
Inverse of Control(控制反转):实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,控制权发生了反转,这就是 Spring 的 IoC 思想
IOC容器
Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext。
BeanFactory 是基础类型的 IoC 容器,ApplicationContext 是 BeanFactory 的子接口,也被称为应用上下文
BeanFactory 和 ApplicationContext 都是通过 XML 配置文件加载 Bean 的
主要区别在于,如果 Bean 的某一个属性没有注入,则使用 BeanFacotry 加载后,在第一次调用 getBean() 方法时会抛出异常,而 ApplicationContext 则在初始化时自检,这样有利于检查所依赖的属性是否注
<!--导入依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<!--新建applicationContext.xml文件-->
<!--约束-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
实例化方式
创建对象
1、构造方法例化
<!--无参构造-->
<bean id="person1" class="com.mengma.instance.constructor.Person1" />
<!--有参构造:参数个数-->
<bean id="user" class="com.tmy.pojo.User">
<constructor-arg index="0" value="tian" />
<constructor-arg index="1" value="12" />
</bean>
<!--有参构造:参数类型-->
<bean id="user" class="com.tmy.pojo.User">
<constructor-arg type="java.lang.String" value="meng" />
<constructor-arg type="int" value="13" />
</bean>
<!--有参构造:参数名-->
<bean id="user" class="com.tmy.pojo.User">
<constructor-arg name="name" value="yu" />
<constructor-arg name="age" value="14" />
</bean>
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) cpx.getBean("user");
2、静态工厂实例化
3、实例工厂实例化
依赖注入(注入参数)
Spring 容器在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,这样,调用者通过 Spring 容器获得被调用者实例
依赖注入主要有两种实现方式,分别是属性 setter 注入和构造方法注入(同上,参数可以是对象,ref )
setter注入
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String, String> card;
private Set<String> games;
private String wife;
private Properties info;
// 注意要生成set方法
<bean id="address" class="com.tmy.pojo.Address"></bean>
<bean id="user" class="com.tmy.pojo.User">
<property name="name" value="tian" />
<property name="address" ref="address" />
<property name="books">
<array>
<value>红楼</value>
<value>西游</value>
</array>
</property>
<property name="hobbys">
<list>
<value>打游戏</value>
<value>睡觉</value>
</list>
</property>
<property name="card">
<map>
<entry key="1" value="1"/>
<entry key="2" value="2"/>
</map>
</property>
<property name="games">
<set>
<value>飞机</value>
<value>大战</value>
</set>
</property>
<property name="wife">
<null />
</property>
<property name="info">
<props>
<prop key="url">asdfsafdasfds</prop>
<prop key="name">123</prop>
</props>
</property>
</bean>
命名空间注入
前提:需要导入对应的约束
p-namespace:用在set方法上注入
xmlns:c="http://www.springframework.org/schema/c"
<bean id="address" class="com.tmy.pojo.Address" c:name="河北"/>
c-namespace:用在构造方法注入
xmlns:p="http://www.springframework.org/schema/p"
<bean id="address" class="com.tmy.pojo.Address" p:name="河北"/>
作用域
1)singleton
单例模式,使用 singleton 定义的 Bean 在 Spring 容器中只有一个实例,这也是 Bean 默认的作用域。
2)prototype
原型模式,每次通过 Spring 容器获取 prototype 定义的 Bean 时,容器都将创建一个新的 Bean 实例。
3)request
在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Request 内有效。
4)session
在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。
5)global Session
在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。
<bean id="person" class="com.mengma.scope.Person" scope="singleton"/>
生命周期
Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
而对于 prototype 作用域的 Bean,Spring 只负责创建
bean装配
Bean 的装配可以理解为依赖关系注入,Bean 的装配方式也就是 Bean 的依赖注入方式。
1、xml装配bean:构造方法注入,setter方法注入
2、Annotation装配bean
导入约束:context
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
开启注解的支持
<!--指定扫描包,包下的注解生效-->
<context:component-scan base-package="com.tmy.*" />
<context:annotation-config />
// 1、描述 Spring 中的 Bean
@Component:泛化的概念
@Repository:访问层(DAO层)
@Service:业务层(Service 层)
@Controller:控制层
// 2、对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,注入依赖
@Autowired:按照 Bean 的类型进行装配
@Resource:按照 Bean 实例名称进行装配
/*
@Resource 中有两个重要属性:name 和 type。
Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。
如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
*/
@Qualifier
与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
3、自动装配
byName:根据 Property 的 name 自动装配
byType:根据 Property 的数据类型(Type)自动装配
constructor:根据构造方法的参数的数据类型,进行 byType 模式的自动装配
AOP
Aspect Oriented Programming(面向切面编程):AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,将业务逻辑的各个部分进行隔离,主要体现在事务处理、日志管理、权限控制、异常处理等方面
Joinpoint(连接点):指那些被拦截到的点,在 Spring 中,可以被动态代理拦截目标类的方法。
Pointcut(切入点):指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。
Advice(通知):指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。
Target(目标):指代理的目标对象。
Weaving(植入) :指把增强代码应用到目标上,生成代理对象的过程。
Proxy(代理):指生成的代理对象。
Aspect(切面):切入点和通知的结合。
通知类型接口
MethodBeforeAdvice(前置通知)
AfterReturningAdvice(后置通知)
MethodInterceptor(环绕通知)
ThrowsAdvice(异常通知)
IntroductionInterceptor(引介通知)
<!--导入apo约束-->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
Spring api接口切面
<!--方法实现通知类型接口-->
<aop:config>
<!--切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.tmy.dao.UserServiceImpl.*(..))"/>
<!--执行环绕增加-->
<!--advice-ref(通知),pointcut-ref(切入点)-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut" />
</aop:config>
Spring 自定义类
<!--自定义切面-->
<aop:config>
<aop:aspect ref="userService">
<aop:pointcut id="pointcut" expression="execution(* com.tmy.dao.UserServiceImpl.*(..))"/>
<aop:before method="before" pointcut-ref="log" />
</aop:aspect>
</aop:config>
注解定义
@Aspect
public class PointClass {
@Before("execution(* com.tmy.dao.UserServiceImpl.*(..))")
public void before() {
System.out.println("12341234");
}
}
事务处理
Spring 的事务管理是基于 AOP 实现的,而 AOP 是以方法为单位的。
<!--mybatis依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--引入 myBatis-spring 依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--引入 spring-jdbc 依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
spring配置文件添加mybatis配置
<!--dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
<!--绑定mybatis配置文件地址-->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!--绑定mybatis映射文件地址-->
<property name="mapperLocations" value="classpath:com/tmy/mapper/*.xml" />
</bean>
<!--mybatis其他设置放到自己配置文件-->
<!--1、配置sqlSession模板-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!--2、不配置sqlSession模板-->
Dao调用类要继承SqlSessionDaoSupport
声明式事务(AOP横切插入)
Spring 的配置文件中创建一个 DataSourceTransactionManager
对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
导入事务的约束
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/context/spring-tx.xsd
<!--配置通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.tmy.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
</aop:config>
编程式事务
/spring-tx.xsd
<tx:advice id=“txAdvice” transaction-manager=“transactionManager”>
tx:attributes
<tx:method name="*" propagation=“REQUIRED”/>
</tx:attributes>
</tx:advice>
aop:config
<aop:pointcut id=“txPointCut” expression=“execution(* com.tmy.dao..(…))”/>
<aop:advisor advice-ref=“txAdvice” pointcut-ref=“txPointCut” />
</aop:config>
### 编程式事务