Java面试题2018---J2EE后端---Spring

1、Spring原理图及解释

从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。

  Spring Core:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

  Spring Context:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

  Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。

  Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

  Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

  Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

  Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

2、Spring 有哪些特性

内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。  
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过  配置类达到的。  

Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。  

3、Sping 常用 jar 包有哪些

4、Spring 的 IOC(控制反转),主要的作用是什么,程序中如何体现 Spring 的控制
反转

所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。

实现流程:

1、依赖注入发生的时间

2、AbstractBeanFactory通过getBean向IoC容器获取被管理的Bean:

3、AbstractAutowireCapableBeanFactory创建Bean实例对象:

4、createBeanInstance方法创建Bean的java实例对象:

5、SimpleInstantiationStrategy类使用默认的无参构造方法创建Bean实例化对象:

6、populateBean方法对Bean属性的依赖注入:

7、BeanDefinitionValueResolver解析属性值:

8、BeanWrapperImpl对Bean属性的依赖注入:

5、静态工厂方法和动态工厂的异同

静态工厂方法:

public class StaticFactory {
    public static Father createInstance() {
        return new Son();
    }
}

实例工厂方法:

1 public class HelloWorldFactory {
2     public HelloWorld createHelloWorld(){
3         return new HelloWorld();
4     }
5 }
6 HelloWorldFactory helloFactory = new HelloWorldFactory();
7 helloFactory.createHelloWorld();

6、bean 的作用域有哪些?各有什么不同

Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession

解释:

singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。

定义不同作用域的java类:

@Component  
@Scope( "session")  
public class SessionObj {  
  
}  
@Component  
@Scope( "request")  
public class RequestObj {  
  
}  
@Component  
@Scope( "prototype")  
public class PrototypeObj {  
  
}  
@Component  
@Scope( "singleton")  
public class SingletonObj {  
  
}  
--------------------- 
作者:大胡子叔叔_ 
来源:CSDN 
原文:https://blog.csdn.net/panhaigang123/article/details/79452064 
版权声明:本文为博主原创文章,转载请附上博文链接!

现在开发应用大多数都是无状态的,所以单例多线程是比较好的实现方式,多例的比较有利于保存状态,完全没必要。

7、bean 的生命周期

找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下。

    在说明前可以思考一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;

    Spring上下文中的Bean也类似,如下

    1、实例化一个Bean--也就是我们常说的new;

    2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;

    3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值

    4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);

    5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);

    6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;

    7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。

    8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;

    注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。

    9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;

    10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

 

以上10步骤可以作为面试或者笔试的模板,另外我们这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了。

参考:https://www.cnblogs.com/kenshinobiy/p/4652008.html

8、属性注入方式有哪三种

常用的注入方式主要有三种:构造方法注入(借助xml),setter注入(借助xml),基于注解的注入。

构造方法注入:

setter注入:

基于注解的注入:

此问题参考博客:https://blog.csdn.net/a909301740/article/details/78379720

9、Spring 中什么是自动装配

 或者:

set注入和构造注入有时在做配置时比较麻烦。所以框架为了提高开发效率,提供自动装配功能,简化配置。Spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean>标签的autowire属性

或者:

所谓自动装配,就是将一个Bean注入到其他Bean的Property中

 

或者:

此题参考博客:https://www.cnblogs.com/sysman/p/4485199.html

10、Spring 中怎样实现自动扫描

参考:https://blog.csdn.net/qq_36098284/article/details/80663860

11、@AutoWired 、@Qualifier 、@Resource

12、静态代理和动态代理的关系,有哪些角色和方式

Proxy代理模式是一种结构型设计模式;代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。但是切记,代理类和委托类要实现相同的接口,因为代理真正调用的还是委托类的方法。

按照代理的创建时期,代理类可以分为两种: 

1)什么是静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了;即静态代理类只能为特定的接口(Service)服务。如想要为多个接口服务则需要建立很多个代理类;

静态代理缺点:

1)代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

2)代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。

2)什么是动态代理:在程序运行时运用反射机制动态创建而成;可以通过一个代理类完成全部的代理功能;动态代理是在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象;在Java中要想实现动态代理机制,需要java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy 类的支持

java.lang.reflect.InvocationHandler接口的定义如下:

//Object proxy:被代理的对象
//Method method:要调用的方法
//Object[] args:方法调用时所需要参数
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

java.lang.reflect.Proxy类的定义如下:

//CLassLoader loader:类的加载器
//Class<?> interfaces:得到全部的接口
//InvocationHandler h:得到InvocationHandler接口的子类的实例
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

动态代理实现代码:

使用代理类:

注:通过newProxyInstance函数我们就获得了一个动态代理对象。

可以看到,我们可以通过LogHandler代理不同类型的对象,如果我们把对外的接口都通过动态代理来实现,那么所有的函数调用最终都会经过invoke函数的转发,因此我们就可以在这里做一些自己想做的操作,比如日志系统、事务、拦截器、权限控制等。这也就是AOP(面向切面编程)的基本原理。

动态代理的优点:

动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。而且动态代理的应用使我们的类职责更加单一,复用性更强

动态代理的缺点:

动态代理在运行期通过接口动态生成代理类,这为其带来了一定的灵活性,但这个灵活性却带来了两个问题,第一代理类必须实现一个接口,如果没实现接口会抛出一个异常。第二性能影响,因为动态代理使用反射的机制实现的,首先反射肯定比直接调用要慢,经过测试大概每个代理类比静态代理多出10几毫秒的消耗。其次 使用反射大量生成类文件可能引起Full GC造成性能影响,因为字节码文件加载后会存放在JVM运行时区的方法区(或者叫持久代)中,当方法区满的时候,会引起Full GC,所以当你大量使用动态代理时,可以将持久代设置大一些,减少Full GC次数。

jdk动态代理

从JDK 1.3以来,Java 语言通过java.lang.reflex库提供的三个类直接支持代理:

java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler 和Method.

被代理类:

package com.mahoutchina.pattern.proxy.dynamicproxy;

public interface BookFacade {
	public void addBook();
	public void deleteBook();
}
package com.mahoutchina.pattern.proxy.dynamicproxy;

public class BookFacadeImpl implements BookFacade {

	@Override
	public void addBook() {
		System.out.println("add book logic is running。。。"); 
	}

	@Override
	public void deleteBook() {
		System.out.println("delete book logic is running。。。");
		
	}
	

}

代理类:

package com.mahoutchina.pattern.proxy.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class BookFacadeProxy implements InvocationHandler {
	private Object target;

	/**
	 * 
	 * @param target
	 * @return
	 */
	public Object bind(Object target) {
		this.target = target;
		// 取得代理对象
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result=null;
		System.out.println("Proxy start...");
		System.out.println("method name:"+method.getName());
		result=method.invoke(target, args);
		System.out.println("Proxy end...");
		return result;
	}

}

InvocationHandler: 这个类在业务委托类执行时,会先调用invoke方法。invoke方法再执行相应的代理操作,可以实现对业务方法的再包装

测试:

 package com.mahoutchina.pattern.proxy.dynamicproxy;

public class TestProxy {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BookFacadeProxy proxy = new BookFacadeProxy();
		BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());
		bookProxy.addBook();
		bookProxy.deleteBook();
	}

}

Cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
  使用动态字节码生成技术实现AOP原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口。

Cglib是一个强大的,高性能的Code生成类库,它可以在运行期间扩展Java类和实现Java接口,它封装了Asm,所以使用Cglib前需要引入Asm的jar

被代理类:

package net.battier.dao.impl;

/**
 * 这个是没有实现接口的实现类
 * 
 * @author student
 * 
 */
public class BookFacadeImpl1 {
	public void addBook() {
		System.out.println("增加图书的普通方法...");
	}
}

代理类: 

package net.battier.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 使用cglib动态代理
 * 
 * @author student
 * 
 */
public class BookFacadeCglib implements MethodInterceptor {
	private Object target;

	/**
	 * 创建代理对象
	 * 
	 * @param target
	 * @return
	 */
	public Object getInstance(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		// 回调方法
		enhancer.setCallback(this);
		// 创建代理对象
		return enhancer.create();
	}

	@Override
	// 回调方法
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("事物开始");
		proxy.invokeSuper(obj, args);
		System.out.println("事物结束");
		return null;


	}

}

测试:

package net.battier.test;

import net.battier.dao.impl.BookFacadeImpl1;
import net.battier.proxy.BookFacadeCglib;

public class TestCglib {
	
	public static void main(String[] args) {
		BookFacadeCglib cglib=new BookFacadeCglib();
		BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());
		bookCglib.addBook();
	}
}

总结:

纵观静态代理与动态代理,它们都能实现相同的功能,而我们看从静态代理到动态代理的这个过程,我们会发现其实动态代理只是对类做了进一步抽象和封装,使其复用性和易用性得到进一步提升而这不仅仅符合了面向对象的设计理念,其中还有AOP的身影,这也提供给我们对类抽象的一种参考。关于动态代理与AOP的关系,个人觉得AOP是一种思想,而动态代理是一种AOP思想的实现!动态代理中运用了反射!!!

为了保持行为的一致性,代理类和委托类通常会实现相同的接口

本题参考博文:

https://blog.csdn.net/hejingyuan6/article/details/36203505

https://blog.csdn.net/qq_34310242/article/details/78046384

13、AOP 的代理模式解析

AOP的基本概念:

AOP即Aspect-Oriented Programming的缩写,中文的意思是面向切面(或方面)编程。它是一种思想,可在不改变程序源码的情况下为程序添加额外的功能;

AOP的应用场景:

性能监控,在方法调用前后记录调用时间,方法执行太长或超时报警。
缓存代理,缓存某方法的返回值,下次执行该方法时,直接从缓存里获取。
软件破解,使用AOP修改软件的验证类的判断逻辑。
记录日志,在方法执行前后记录系统日志。
工作流系统,工作流系统需要将业务代码和流程引擎代码混合在一起执行,那么我们可以使用AOP将其分离,并动态挂接业务。
权限验证,方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉。 

AOP代理则可分为静态代理和动态代理两大类:

其中静态代理是指使用AOP框架提供的命令进行编译,从而在编译阶段就可生成AOP代理类,因此也称为编译时增强;而动态代理则在运行时借助于JDK动态代理、CGLIB等在内存中“临时”生成AOP动态代理类,因此也被称为运行时增强。

参考博客:https://blog.csdn.net/session_time/article/details/52603870

Spring配置文件中Aop配置:

测试spring动态代理:

spring AOP原理

  1、当spring容器启动的时候,加载两个bean,对像个bean进行实例化
  2、当spring容器对配置文件解析到<aop:config>的时候,把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean
  3、如果匹配成功,则为该bean创建代理对象
  4、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象,如果没有代理对象,则返回对象本身

参考博客:https://www.cnblogs.com/dooor/p/5326759.html

AOP其实就是一种拦截器,在一个业务方法执行前或执行后、甚至在抛出异常时执行的一段切面逻辑。

而AOP的底层实现是动态代理,所以,首先你必须对动态代理有很好的理解。我们经常使用的两种代理技术是JDK动态代理与CGLIB动态代理,而在JDK动态代理中,我们必须使用接口。

拦截器:

 

底层的动态代理实现方式:

   如果你对SpringAOP框架有所了解的话,就会知道这就是Spring中的前置通知与后置通知的实现原理!

14、AOP 运行流程

可参考博客:http://www.cnblogs.com/liyafei/p/9330069.html

核心就是运用了动态代理

15、JavaEE 中事务隔离级分为哪些,分别是什么,代表什么含义

事务的四大特性和隔离级别
事务的四大特性
原子性(Atomicity)

指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。转账前和转账后的总金额不变。

隔离性

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

持久性

指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

在知道隔离级别之前,我们先知道以下几个概念:
赃读

事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有 另外一个事务插入数据造成的

不可重复读

 一 个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交。

虚读(幻读)

虚读(幻读)事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有 另外一个事务插入数据造成的

事务的隔离级别
READ UNCOMMITED(读未提交):脏读、不可重复读、幻读都有可能发生。安全级别最低。

READ COMMITED(读已提交):可避免脏读的发生。Orcale默认。

REPEATABLE READ(可重复读):可避免脏读、不可重复读的发生。MySQL默认。

SERIALIZABLE(串行化):可避免脏读、不可重复读、幻读。安全级别最高。

MySQL设置事务隔离级别
SELECT @@TX_ISOLATION:查看当前的事务隔离级别。
SET TRANSACTION ISOLATION LEVEL 隔离级别名称 :更改当前隔离级别。

设置隔离级别必须在事务之前

JDBC控制事务的隔离级别
Connection.setTransactionIsolation(int level)

参数: 
- TRANSACTION_NONE:不支持事务

TRANSACTION_READ_UNCOMMITED:可发生脏读,不重复读和虚读。

TRANSACTION_READ_COMMITED:不可发生脏读。

TRANSACTION_REPEATABLE READ:不可发生脏读和不重复读。

TRANSACTION_SERIALIZABLE:不可发生脏读、不可重复读和虚读。

或者:

设置@Transactional(isolation=Isolation.DEFAULT)

@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,
isolation=Isolation.DEFAULT)
	public void saveUser(Map<String, String> map) throws Exception {
         System.out.println("方法开始");
		for (int i = 0; i < 500000; i++) {
	            System.out.println("*");
	        }
		 System.out.println("进入保存");
		 userDao.saveUser(map);
		 System.out.println("退出保存");

}


参考博客:https://blog.csdn.net/qq_33689414/article/details/60961237 

16、Spring 事务管理有哪几个核心组件

核心类

Spring事务管理的核心接口是PlatformTransactionManager 


 事务管理器接口通过getTransaction(TransactionDefinition definition)方法根据指定的传播行为返回当前活动的事务或创建一个新的事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。 
在TransactionDefinition接口中定义了它自己的传播行为和隔离级别 
 
除去常量,主要的方法有:

int getIsolationLevel();// 返回事务的隔离级别
String getName();// 返回事务的名称
int getPropagationBehavior();// 返回事务的传播行为
int getTimeout();  // 返回事务必须在多少秒内完成
boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的
Spring配置事务管理器

先配置如下代码:

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

Spring提供了两种事务管理的方式:编程式事务管理和声明式事务管理,让我们分别看看它们是怎么做的吧。

1)编程式事务管理:

编程式事务管理我们可以通过PlatformTransactionManager实现来进行事务管理,同样的Spring也为我们提供了模板类TransactionTemplate进行事务管理,下面主要介绍模板类,我们需要在配置文件中配置

  <!--配置事务管理的模板-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
        <!--定义事务隔离级别,-1表示使用数据库默认级别-->
        <property name="isolationLevelName" value="ISOLATION_DEFAULT"></property>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"></property>
    </bean>

方法中需要加入事物管理的代码:

2)声明式事务管理

声明式事务管理有两种常用的方式,一种是基于tx和aop命名空间的xml配置文件,一种是基于@Transactional注解,随着Spring和Java的版本越来越高,大家越趋向于使用注解的方式,下面我们两个都说。 
1.基于tx和aop命名空间的xml配置文件 
配置文件

 <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert" propagation="REQUIRED" read-only="false"  rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="pointCut" expression="execution (* com.gray.service.*.*(..))"/>
        <aop:advisor advice-ref="advice" pointcut-ref="pointCut"/>
    </aop:config>

2.基于@Transactional注解 
这种方式最简单,也是最为常用的,只需要在配置文件中开启对注解事务管理的支持。

<!-- 声明式事务管理 配置事物的注解方式注入-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

然后在需要事务管理的地方加上@Transactional注解,如:

 @Transactional(rollbackFor=Exception.class)
    public void insert(String sql, boolean flag) throws Exception {
        dao.insertSql(sql);
        // 如果flag 为 true ,抛出异常
        if (flag){
            throw new Exception("has exception!!!");
        }
    }

rollbackFor属性指定出现Exception异常的时候回滚,遇到检查性的异常需要回滚,默认情况下非检查性异常,包括error也会自动回滚。 

本题参考博客:https://blog.csdn.net/donggua3694857/article/details/69858827

17、OpenSessionInView 有什么作用

18、BeanFactory 和 ApplicationContext 有什么区别

19、Spring Bean 的作用域之间有什么区别

Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession

singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。

配置方式:

现在开发应用大多数都是无状态的,所以单例多线程是比较好的实现方式,多例的比较有利于保存状态,完全没必要。

参考博客:https://blog.csdn.net/panhaigang123/article/details/79452064

20、Spring 框架中有哪些不同类型的事件

Spring 提供了以下5中标准的事件:

  • 上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
  • 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
  • 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  • 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  • 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

21、Spring 框架中都用到了哪些设计模式

Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:

  • 代理模式—在AOP和remoting中被用的比较多。
  • 单例模式—在spring配置文件中定义的bean默认为单例模式。
  • 模板方法—用来解决代码重复的问题。
  • 前端控制器—Srping提供了DispatcherServlet来对请求进行分发。
  • 视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
  • 依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
  • 工厂模式—BeanFactory用来创建对象的实例。

22、基于 Java 配置的方式配置 Spring

 

 

======以下于你或许是个好消息======

 

好消息就是:欢迎访问下面的博客网站哈哈哈......


网站名称:Java学习笔记网 (点击进入)

url:https://www.javaxxbj.com/ (点击进入)

网站特点:

  1. java主要网站的导航目录
  2. 你可以记录自己的博客,并可以控制显示和隐藏,可利于管理啦!!!
  3. 可以添加收藏各个网站的链接!!!
  4. 甚至也可以文章收藏,点赞,关注,查看我的消息等功能哦!!1

看一小点点的截图:

或可一试哦!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值