CORS 规范区分了预检请求、简单请求和实际请求。要了解 CORS 的工作原理,您可以阅读本文等,或查看规范以获取更多详细信息。
Spring MVC HandlerMapping 实现为 CORS 提供了内置支持。成功将请求映射到处理程序后,HandlerMapping 实现会检查给定请求和处理程序的 CORS 配置并采取进一步行动。预检请求被直接处理,而简单和实际的 CORS 请求被拦截、验证,并设置了所需的 CORS 响应标头。
为了启用跨域请求(即 Origin 标头存在且与请求的主机不同),您需要有一些显式声明的 CORS 配置。如果未找到匹配的 CORS 配置,则拒绝预检请求。没有将 CORS 标头添加到简单和实际 CORS 请求的响应中,因此浏览器会拒绝它们。
The context may or may not yet be refreshed. If it (a) is an implementation of ConfigurableWebApplicationContext and (b) has not already been refreshed (the recommended approach), then the following will occur: If the given context has not already been assigned an id, one will be assigned to it ServletContext and ServletConfig objects will be delegated to the application context customizeContext will be called Any ApplicationContextInitializer org.springframework.context.ApplicationContextInitializer ApplicationContextInitializers specified through the "contextInitializerClasses" init-param will be applied. refresh() will be called
publicinterfaceTransactionDefinition{ int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; // same as java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; int ISOLATION_READ_COMMITTED = 2; // same as java.sql.Connection.TRANSACTION_READ_COMMITTED; int ISOLATION_REPEATABLE_READ = 4; // same as java.sql.Connection.TRANSACTION_REPEATABLE_READ; int ISOLATION_SERIALIZABLE = 8; // same as java.sql.Connection.TRANSACTION_SERIALIZABLE; int TIMEOUT_DEFAULT = -1;
While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this behavior.
You can apply the @Transactional annotation to an interface definition, a method on an interface, a class definition, or a public method on a class. However, the mere presence of the @Transactional annotation is not enough to activate the transactional behavior. The @Transactional annotation is merely metadata that can be consumed by some runtime infrastructure that is @Transactional-aware and that can use the metadata to configure the appropriate beans with transactional behavior. In the preceding example, the <tx:annotation-driven/> element switches on the transactional behavior.
@EnableTransactionManagement and <tx:annotation-driven/> looks for @Transactional only on beans in the same application context in which they are defined. This means that, if you put annotation-driven configuration in a WebApplicationContext for a DispatcherServlet, it checks for @Transactional beans only in your controllers and not your services. See MVC for more information.
@EnableTransactionManagement and <tx:annotation-driven/> 只会在定义它们本身的上下文中寻找 @Transactional 注解的 bean, 如果是在 Web 应用的 DispatcherServlet 对应的 WebApplicationContext@EnableTransactionManagement and <tx:annotation-driven/>只会在这个上下文中查找,这个上下文一般只会定义控制器以及试图解析器等 web 组件,而不是 service 类。
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behavior, so you should not rely on this feature in your initialization code (that is, @PostConstruct).
由于 Spring 事务是基于代理的,只有通过代理的外部方法调用才会被拦截,目标对象内部的方法调用(一个方法调用对象内部的另一个方法)是不会在运行时导致一个实际的事务发生的;另外,必须完全初始化代理以提供预期的行为,因此不应在初始化代码(即@PostConstruct)中依赖此功能。
Consider using of AspectJ mode (see the mode attribute in the following table) if you expect self-invocations to be wrapped with transactions as well. In this case, there no proxy in the first place. Instead, the target class is woven (that is, its byte code is modified) to turn @Transactional into runtime behavior on any kind of method.
// single TransactionTemplate shared amongst all methods in this instance privatefinal TransactionTemplate transactionTemplate;
// use constructor-injection to supply the PlatformTransactionManager publicSimpleService(PlatformTransactionManager transactionManager){ this.transactionTemplate = new TransactionTemplate(transactionManager); }
public Object someServiceMethod(){ return transactionTemplate.execute(new TransactionCallback() { // the code in this method executes in a transactional context public Object doInTransaction(TransactionStatus status){ updateOperation1(); return resultOfUpdateOperation2(); } }); } }
也可以提直接使用 PlatformTransactionManager 来管理事务,需要结合 Spring 事务抽象的其它对象: TransactionDefinition, TransactionStatus。 可以实现事务的初始化、回滚和提交。编程式事务也可以显示设置事务的名称,声明式的事务名称一般都是默认的全限定类名+方法名。
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can be done only programmatically def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def); try { // execute your business logic here } catch (MyException ex) { txManager.rollback(status); throw ex; } txManager.commit(status);
Do not call rollback on a transaction if commit threw an exception. The transaction will already have been completed and cleaned up when commit returns, even in case of a commit exception. Consequently, a rollback call after commit failure will lead to an IllegalTransactionStateException.