Spring学习
1.介绍
1.Spring是一个开源的免费的容器框架
2.Spring是一个轻量级的、非入侵式的框架
3.Spring是一个IOC(DI)和AOP容器框架
1.一个快速开发的脚手架,快速开发单个微服务
2.约定大于配置
1.SpringCloud基于SpringBoot实现,是一个微服务治理组件
1. Data Access/Integration(数据访问/集成)
数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。
JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。
2. Web 模块
Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。
Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。
3. Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。
Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。
4. 其他模块
Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。
AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。

2.核心
原逻辑:程序主动创建对象,控制在程序员代码里
控制反转:使用set注入,程序不在主动创建对象,而是被动接收对象。大大降低耦合性
控制反转是通过DI(依赖注入)实现的,有三种注入方式:构造方法注入、set注入(最重要)、c命名空间和p命名空间注入(需要在xml文件中头添加相应约束)
<bean id="person" class="com.lmy.entity.Person">
<property name="id" value="1"/>
<property name="name" value="lmy"/>
</bean>
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Person person = (Person) context.getBean("person");
System.out.println(person);
1.通过无参构造方法。(默认方式)
2.通过有参构造(没有无参构造)<bean>中使用<constructor-arg>配置
1.Singleton 单例 2.prototype原型模式(多例) 3.request 4.session 5.application
1.含义:自动装配是Spring满足bean依赖的一种方式,Spring会在上下文中自动寻找并被bean装配属性
2.三种方式: xml中装配、java配置文件基于注解装配、隐式的自动装配(重要)
3.结合配置文件使用byName/byType方式自动装配
3.1 <bean id="person" class="com.lmy.entity.Person" autowire="byName/byType"></bean>
3.2 使用注解:@Autowired(只按照byType,Spring注解) 多个bean时结合@Qualifier注解指定name
3.3 使用@Resource(默认byName,找不到也可byType)注解 J2EE注解
使用注解时使用配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- 确定使用注解 -->
<context:annotation-config></context:annotation-config>
<!-- 自动扫描指定的包 -->
<context:component-scan base-package="cn.spring.demo"></context:component-scan>
</beans>
3.4 注解说明
@Component 放在类上,说明这个类被Spring管理了,相当于bean
衍生注解:@Controller @Service @Mapper
@Nullable 字段标记了这个注解,说明这个字段可以为null
@Value 相当于<property name="id" value="1"/>
@Import 相当于配置文件中的<import>,代表着把多个配置类合并
4.代码方式进行装配(不再需要配置文件,SpringBoot的最常见方式)
@Configuration+@Bean注解配合使用,代表是一个配置类,方法注册为一个bean,方法返回值就是<bean>标签的class
//注解方式获取Spring上下文对象
ApplicationContext context1 = new AnnotationConfigApplicationContext("com.lmy.*");
Person person1 = (Person) context.getBean("getPerson");//getBean方法有@Bean注解
System.out.println(person1);
1.静态代理:抽象角色、代理角色、真实角色、用户角色;
代理角色代理真实角色向用户角色提供使用,比真实角色增加附加功能
2.动态代理:代理角色不用自己写,是动态角色(基于反射实现)
基于接口:JDK动态代理。基于类:CGLIB动态代理
java字节码:javasist JBoss容器使用,Tomcat不用
2.1 JDK动态代理:InvocationHandler(实现了这个接口)、Proxy(提供静态方法创建代理对象)
public class ProxyLearn implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行方法
Object invoke = method.invoke(target, args);
return invoke;
}
}
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
1.xml配置(第一种自定义类;第二种定义一个切面类)
<bean id="diy" class="com.diy.DiyPointcut">
</bean>
<aop:config>
<!--自定义切面-->
<!--配置aop-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.service.*.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
2.基于注解
@Aspect//标注这个类是一个切面
@Order(1)//越小优先级越大
@Component
public class Annotation1 {
@Before("execution(* com.lmy.proxylearn.*.*(..))")
public void before(){
System.out.println("before");
}
@After("execution(* com.lmy.proxylearn.*.*(..))")
public void after(){
System.out.println("after");
}
//在环绕增强中,我们可以给一个参数,代表我们要获取切入的点
@Around("execution(* com.lmy.proxylearn.*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around");
Object proceed = joinPoint.proceed();
System.out.println("after around");
return proceed;
}
}
3.整合mybatis
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<configuration>
<typeAliases>
<package name="com.pojo"/>
</typeAliases>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="cacheEnabled" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.6.128:3306/lmy_test" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/test/testMapper.xml"/>
</mappers>
</configuration>
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://111.230.212.103:3306/mybatis?userSSL=true&
userUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="hdk123"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/mapper/UserMapper.xml"/>
</bean>
<bean id="userMapper2" class="com.mapper.UserMapperIml2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="datasource" />
</bean>
<tx:advice id="tx1" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="txpointxut" expression="execution(* com.mapper.*.*(..))"/>
<aop:advisor advice-ref="tx1" pointcut-ref="txpointxut"/>
</aop:config>
4.Spring相关面试题
1.Spring 如何创建bean对象的?Bean的生命周期?
1.1
1.2
1.3
1.4
1.5
1.6 Spring的启动过程
1.解析Bean配置信息,將配置信息转换为BeanDefinition对象,注册到BeanDefinitionRegistry中。
2.执行所有的BeanFactoryPostProcessor的postProcessBeanFactory()方法对Bean工厂信息进行修改,包括修改或新增BeanDefinition对象。注意:如果需要控制BeanFactoryPostProcessor的执行顺序需要实现PriorityOrdered接口,getOrder()方法返回的值越小,执行优先级越高。
3.通过BeanDefinition对象实例化所有Bean,注入依赖。
4.执行所有BeanPostProcessor对象的postProcessBeforeInitialization()方法。
5.执行Bean的初始化方法,例如InitializingBean接口的afterPropertiesSet方法,或init-method属性指定的方法。
6.执行所有BeanPostProcessor对象的postProcessAfterInitialization()方法。
2.Spring怎么解决循环依赖?
2.1 为什么不用二级缓存解决