-
官网:https://docs.spring.io/spring-framework/docs/current/reference/html/overview.html#overview
-
官方下载地址:http://repo.spring.io/release/org/springframework/spring
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.2</version>
</dependency>
1.2. 优点
-
Spring是一个开源的免费的框架(容器)
-
Spring是一个轻量级的,非侵入式的框架
-
控制反转(IOC
Inversion of Control
和面向切面编程(AOPAspect Oriented Programming
) -
支持事务的处理,对框架整合的支持!
总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!
1.3. 组成
-
Spring-Core:Core包是框架的最基础部分,并提供依赖注入(Dependency Injection)管理Bean容器功能。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
-
Spring-Context:核心模块的BeanFactory使Spring成为一个容器,而上下文模块使它成为一个框架。这个模块扩展了BeanFactory的概念,增加了消息、事件传播以及验证的支持。另外,这个模块提供了许多企业服务,例如电子邮件、JNDI访问、EJB集成、远程以及时序调度(scheduling)服务。也包括了对模版框架例如Velocity和FreeMarker集成的支持。
-
Spring-Aop:Spring在它的AOP模块中提供了对面向切面编程的丰富支持。例如方法拦截器(servletListener ,controller....)和切点,可以有效的防止代码上功能的耦合,这个模块是在Spring应用中实现切面编程的基础。Spring的AOP模块也将元数据编程引入了Spring。使用Spring的元数据支持,你可以为你的源代码增加注释,指示Spring在何处以及如何应用切面函数。
-
Spring-Dao:使用JDBC经常导致大量的重复代码,取得连接、创建语句、处理结果集,然后关闭连接、旧代码中迁移自定义工具类JDBCUtil 也让开发变得繁琐。Spring的Dao模块对传统的JDBC进行了抽象,还提供了一种比编程性更好的声明性事务管理方法。
-
Spring-Web:Web上下文模块建立于应用上下文模块之上,提供了WEB开发的基础集成特性,例如文件上传。另外,这个模块还提供了一些面向服务支持。利用Servlet listeners进行IOC容器初始化和针对Web的applicationcontext。
-
Spring Web MVC:(Model-View-Controller)Spring为构建Web应用提供了一个功能全面的MVC框架。它提供了一种清晰的分离模型,在领域模型代码和web form之间。并且,还可以借助Spring框架的其他特性。
-
Spring-ORM:关系映射模块,ORM包为流行的“关系/对象”映射APIs提供了集成层,包括JDO,Hibernate和iBatis(MyBatis)。通过ORM包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,方便开发时小组内整合代码。
spring-01-ioc1
3. HelloSpringspring-02-hellospring
4. IOC创建对象的方式
- 使用无参构造创建!默认
- 有参构造创建
- 别名
<!-- 别名 -->
<alias name="user" alias="xiaofan"/>
- Bean的配置
<!--使用spring来创建对象,在spring这些都是bean-->
<bean id="hello" class="com.xiaofan.pojo.Hello" name="hello2, h2">
<property name="name" value="spring..."/>
</bean>
6. 依赖注入spring-03-di
-
构造方法注入
-
set方式注入[重点]
- 依赖: bean对象的创建依赖容器
- 注入:bean对象中的所有属性,由容器来注入!
-
拓展方式注入
注意点:p命名和c命名空间不能直接使用,需要导入xml约束!
-
bean的作用域
- 单例模式(Spring默认机制)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p命名空间注入,可以直接注入属性的值:property--> <bean id="user" class="com.xiaofan.pojo.User" p:name="张三" p:age="18"/> <!--c命名空间注入,通过构造器注入;construct-args--> <bean id="u" class="com.xiaofan.pojo.User" c:name="李四" c:age="22" scope="prototype"/> </beans>
-
原型模式
-
其余的request、session、application、这些个只能在web开发中使用
-
bean
@Component
-
属性如何注入
@Value("kuangshen")
-
衍生的注解
-
自动装配配置
@Autowired @Qualifier @Resource
-
作用域
@Scope
spring-07-appconfig
package com.xiaofan.config;
import com.xiaofan.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* 这个也会被spring容器托管,注册到容器中,因为他本来就是一个@Component
* @Configuration代表这是一个配置类,就和我们之前看到的beans.xml一样
*/
@Configuration
@ComponentScan("com.xiaofan.pojo")
@Import(MyConfig.class)
public class AppConfig {
/**
* 注册一个bean,就相当于我们之前写的一个bean标签
* 这个方法的名字,就相当于bean标签中的id属性
* 这个方法的返回值,就相当于bean标签中的class属性
*/
@Bean
public User getUser() {
return new User();
}
}
10. 代理模式spring-08-proxy
- 静态代理
- 动态代理
- 方式一 (使用原生的Spring API接口)
package com.xiaofan.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
// method: 要执行的目标对象的方法
// args: 参数
// target: 目标对象
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.xiaofan.service.UserServiceImpl" />
<bean id="log" class="com.xiaofan.log.Log" />
<bean id="alterLog" class="com.xiaofan.log.AfterLog"/>
<!--方式1: 使用原生的Spring API接口-->
<!--配置aop:需要导入aop的约束-->
<aop:config>
<!-- 切入点: expression: 表达式,execution(要执行的位置!* 修饰符 * 返回值 * 类名 * 方法名 * 参数) -->
<aop:pointcut id="pointcut" expression="execution(* com.xiaofan.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加!-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="alterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
import com.xiaofan.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.query();
}
}
- 方式二(使用自定义类)
package com.xiaofan.diy;
public class DiyPointCut {
public void before() {
System.out.println("========方法执行前========");
}
public void after() {
System.out.println("========方法执行后========");
}
}
<bean id="diy" class="com.xiaofan.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref 要引用的类-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.xiaofan.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
- 方式三(使用注解实现)
package com.xiaofan.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 使用注解实现AOP
*/
@Aspect
public class AnnotationPointCut {
@Before("execution(* com.xiaofan.service.UserServiceImpl.*(..))")
public void before() {
System.out.println("==方法执行前==");
}
@After("execution(* com.xiaofan.service.UserServiceImpl.*(..))")
public void after() {
System.out.println("==方法执行后==");
}
@Around("execution(* com.xiaofan.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前...");
// 执行方法
Object proceed = joinPoint.proceed();
System.out.println("环绕后...");
}
}
<!--方式三-->
<bean id="annotationPointCut" class="com.xiaofan.diy.AnnotationPointCut"/>
<!--开启aop注解支持-->
<aop:aspectj-autoproxy />
12.整合mybatis
12.1. 整合Mybatis方式一spring-10-mybatis
-
UserMapperImpl
.java
package com.xiaofan.mapper;
import com.xiaofan.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{
// 我们的所有操作,都是用sqlSession来执行,在原来,现在都是用sqlSessionTemplate;
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
return users;
}
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaofan.mapper.UserMapper">
<select id="selectUser" resultType="user">
select * from mybatis.user;
</select>
</mapper>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
<!--给实体类起别名-->
<typeAliases>
<package name="com.xiaofan.pojo"/>
</typeAliases>
<!--设置-->
<!-- <settings>
<setting name="" value=""/>
</settings>-->
</configuration>
- spring-dao.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--DataSource: 使用spring的数据源替代mybatis的配置 c3p0 dbcp druid
我们这里使用spring提供的jdbc: org.springframework.jdbc.datasource.DriverManagerDataSource
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.30:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/xiaofan/mapper/*.xml"/>
</bean>
<!--sqlSessionTemplate:就是我们使用的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造方式注入sqlSessionFactory,因为它没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.xiaofan.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
- MyTest.java
import com.xiaofan.mapper.UserMapper;
import com.xiaofan.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper mapper = context.getBean("userMapper", UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
}
12.2. 整合mybatis方式二
- UserMapperImpl2.java
package com.xiaofan.mapper;
import com.xiaofan.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUser() {
UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
return users;
}
}
- 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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper2" class="com.xiaofan.mapper.UserMapperImpl2" >
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
- spring-dao.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--DataSource: 使用spring的数据源替代mybatis的配置 c3p0 dbcp druid
我们这里使用spring提供的jdbc: org.springframework.jdbc.datasource.DriverManagerDataSource
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.30:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/xiaofan/mapper/*.xml"/>
</bean>
</beans>
13. 声明式事务
- 声明式事务AOP
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.xiaofan.mapper.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!-- 配置声明式事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!-- 结合aop实现事务的植入-->
<!-- 配置事务通知 -->
<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.xiaofan.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
- 编程式事务,需要在代码里进行事务的管理