spring总结

一、SpringMVC工作原理

  1. 用户发送请求至web服务器,web服务器根据web.xml配置匹配到DispatcherServlet。
  2. DispatcherServlet会根据HandlerMapping、HandlerAdapter会找到对应的Handler处理器
  3. Handler处理器处理请求后返回ModelAndView逻辑视图给DispatcherServlet,DispatcherServlet根据ViewReslover视图解析器将ModelAndView解析成真正视图,然后返回给用户

    <mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean。

    第一个是HandlerMapping的实现类,它会处理@RequestMapping 注解,并将其注册到请求映射表中。

    第二个是HandlerAdapter的实现类,它是处理请求的适配器,说白了,就是确定调用哪个类的哪个方法,并且构造方法参数,返回值。

二、Spring中ApplicationContext和beanfactory区别

    1)ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。

ApplicationContext包还提供了以下的功能

  • 提供了支持国际化的文本消息
  • 统一的资源文件读取方式
  • 已在监听器中注册的bean的事件

以下是三种较常见的 ApplicationContext 实现方式:

  1. ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
  2. FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”); 
  3. XmlWebApplicationContext:由Web应用的XML文件读取上下文。

三、Spring的beanFactory和factoryBean的区别

      BeanFactory是spring中比较原始的Factory。提供了IOC容器最基本的形式。FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,可以在getObject()方法中灵活配置

四、SpringIOC和AOP原理 

  4.1 IoC(Inversion of Control)  

     (1). IoC(Inversion of Control)是控制权由应用代码中转到了外部容器,控制反转。IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。   

     (2). 依赖注入的思想是通过反射机制实现的

例:如下spring配置
<bean id="courseDao" class="com.qcjy.learning.Dao.impl.CourseDaoImpl"></bean>

//解析<bean .../>元素的id属性得到该字符串值为“courseDao”
String idStr = "courseDao";
//解析<bean .../>元素的class属性得到该字符串值为“com.qcjy.learning.Dao.impl.CourseDaoImpl”
String classStr = "com.qcjy.learning.Dao.impl.CourseDaoImpl";
//利用反射知识,通过classStr获取Class类对象
Class<?> cls = Class.forName(classStr);
//实例化对象
Object obj = cls.newInstance();
//container表示Spring容器
container.put(idStr, obj);

 IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。

4.2 AOP(Aspect Oriented Programming)

     (1) AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等

     (2) 实现AOP的技术:

  1. 静态代理的代表为AspectJ
  2. 动态代理则以Spring AOP为代表

     (3) 与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。Spring AOP根据被代理的类是否实现了一个接口,是则选择JDK动态代理,反之则选择CGLIB动态代理

  1. JDK动态代理:核心是InvocationHandler接口和Proxy类。通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口,在运行期间创建一个接口的实现类来完成对目标对象的代理。。
  2. CGLIB动态代理:核心是MethodInterceptor接口和Enhancer类。CGLIB是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。性能比JDK强;需要引入包asm.jar和cglib.jar。    

    (4) spring aop两种配置方式 :1、注解配置AOP       2、xml配置aop

  (5)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
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop            
           http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
           "><!-- 要添加最后2行 -->
           
    <context:annotation-config />
    <context:component-scan base-package="com.oumyye"/>
    <bean id="logInterceptor" class="com.oumyye.aop.LogInterceptor"></bean>
    <aop:config>
        <aop:pointcut expression="execution(public * com.oumyye.service..*.add(..))" 
        id="servicePointcut"/>
        <aop:aspect id="logAspect" ref="logInterceptor">
            <aop:before method="before"  pointcut-ref="servicePointcut" />
        </aop:aspect>
        
    </aop:config>
</beans>

(7).Spring切面可以应用五种类型的通知  

  • before:前置通知,在一个方法执行前被调用。
  • after: 在方法执行之后调用的通知,无论方法执行是否成功。
  • after-returning: 仅当方法成功完成后执行的通知。
  • after-throwing: 在方法抛出异常退出时执行的通知。
  • around: 在方法执行之前和之后调用的通知。

详情访问https://blog.csdn.net/qq_33314107/article/details/79468826

              https://blog.csdn.net/qq_33314107/article/details/79468505

五、Spring注入方式

  • 构造方法注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
  • Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
  • 基于注解的注入

六、Spring事务管理

    Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。Spring事务管理器的接口是PlatformTransactionManager,PlatformTransactionManager通过getTransaction(TransactionDefinition definition)方法根据指定的传播行为、隔离级别返回当前活动的事务或创建一个新的事务

è¿éåå¾çæè¿°

6.1 Spring支持两种类型的事务管理:

  • 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
  • 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

6.2 Spring事务的传播行为

  1. propagation_required:如果当前没有事务,就新建一个事务。这是最常见的选择,也是Spring默认的事务的传播。
  2. propagation_requires_new:新建事务,如果当前存在事务,把当前事务挂起(暂停等待)。
  3. propagation_supports:如果当前没有事务,就以非事务方式执行。
  4. propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  5. propagation_mandatory:如果当前没有事务,就抛出异常。
  6. propagation_never:以非事务方式执行,如果当前存在事务,则抛出异常
  7. propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与propagation_required类似的操作

6.3 Spring事务的隔离级别

  1. ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应
  2. ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。
  3. ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
  4. ISOLATION_REPEATABLE_READ:这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。
  5. ISOLATION_SERIALIZABLE:这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读

6.4 并发事务引起的问题

  • 脏读(Dirty reads)——脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
  • 不可重复读(Nonrepeatable read)——不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
  • 幻读(Phantom read)——幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

7、Spring bean生命周期

  • Spring容器 从XML 文件中读取bean,并实例化bean。
  • Spring根据bean的定义填充所有的属性。
  • 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
  • 如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
  • 如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
  • 如果bean实现InitializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用初始化方法。
  • 如果有任何与bean相关联的BeanPostProcessors,这些bean的postProcessAfterInitialization() 方法将被调用。
  • 如果bean实现了 DisposableBean,它将调用destroy()方法。

8、Spring Bean的作用域

Spring容器中的bean可以分为5个范围。全局作用域与Servlet中的session作用域效果相同

  1. singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
  2. prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
  3. request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
  4. Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
  5. global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。

9、Spring Bean的自动装配

     不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。有如下方式:

  1. no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。
  2. byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
  3. byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
  4. constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
  5. autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。

自动装配的局限性是:

  • 重写: 你仍需用 <constructor-arg>和 <property> 配置来定义依赖,意味着总要重写自动装配。
  • 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。
  • 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。

十、Spring常用注解 

使用注解之前要开启自动扫描功能,其中base-package为需要扫描的包(含子包)。 
<context:annotation-config/> 
<context:component-scan base-package="cn.test"/>

@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解 作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、 
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier("personDaoBean") 存在多个实例配合使用
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@PostConstruct 初始化注解
@PreDestroy 摧毁注解 默认 单例  启动就加载
@Async异步方法调用

十一、问题总结

1、Spring框架中的单例bean是线程安全的吗?

     不,Spring框架中的单例bean不是线程安全的

2、Spring中如何注入一个java集合?

    Spring提供以下几种集合的配置元素:

  • <list>类型用于注入一列值,允许有相同的值。
  • <set> 类型用于注入一组值,不允许有相同的值。
  • <map> 类型用于注入一组键值对,键和值都可以为任意类型。
  • <props>类型用于注入一组键值对,键和值都只能为String类型。

3、Spring如何处理线程并发问题?

    Spring使用ThreadLocal解决线程安全问题,ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值