定义了 A B C 三个模块,其中有两个依赖关系 A->B->C->D ,A->E->D,当构建 A时,使用的D是1.0 版本,因为 A-E-D这个依赖关系更短,如果要在构建A时强制使用D2.0版本,可以在A的依赖中明确指定 D2.0,依赖树如下图
1 2 3 4 5 6 7 8
A ├── B │ └── C │ └── D 2.0 ├── E │ └── D 1.0 │ └── D 2.0
依赖域(Dependency Scope)
compile This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. A dependency with this scope is added to the classpath used for compilation and test, but not the runtime classpath. It is not transitive.
runtime This scope indicates that the dependency is not required for compilation, but is for execution. Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath.
test This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. This scope is not transitive. Typically this scope is used for test libraries such as JUnit and Mockito. It is also used for non-test libraries such as Apache Commons IO if those libraries are used in unit tests (src/test/java) but not in the model code (src/main/java).
system This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
import This scope is only supported on a dependency of type pom in the <dependencyManagement> section. It indicates the dependency is to be replaced with the effective list of dependencies in the specified POM’s <dependencyManagement> section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
For security reasons, browsers prohibit AJAX calls to resources residing outside the current origin. For example, as you’re checking your bank account in one tab, you could have the evil.com website in another tab. The scripts from evil.com shouldn’t be able to make AJAX requests to your bank API (withdrawing money from your account!) using your credentials.
Cross-origin resource sharing (CORS) is a W3C specification implemented by most browsers that allows you to specify in a flexible way what kind of cross domain requests are authorized, instead of using some less secured and less powerful hacks like IFrame or JSONP.
Spring MVC provides high-level configuration facilities, described bellow.
Controller method CORS configuration
You can add to your @RequestMapping annotated handler method a @CrossOrigin annotation in order to enable CORS on it (by default @CrossOrigin allows all origins and the HTTP methods specified in the @RequestMapping annotation):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@RestController @RequestMapping("/account") public class AccountController {
@CrossOrigin @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... }
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } }
It is also possible to enable CORS for the whole controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController {
@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... }
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } }
In this example CORS support is enabled for both retrieve() and remove() handler methods, and you can also see how you can customize the CORS configuration using @CrossOrigin attributes.
You can even use both controller and method level CORS configurations, Spring will then combine both annotation attributes to create a merged CORS configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController {
@CrossOrigin(origins = "http://domain2.com") @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... }
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } }
If you are using Spring Security, make sure to enable CORS at Spring Security level as well to allow it to leverage the configuration defined at Spring MVC level.
1 2 3 4 5 6 7 8
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
In addition to fine-grained, annotation-based configuration you’ll probably want to define some global CORS configuration as well. This is similar to using filters but can be declared withing Spring MVC and combined with fine-grained @CrossOrigin configuration. By default all origins and GET, HEAD and POST methods are allowed.
JavaConfig
Enabling CORS for the whole application is as simple as:
1 2 3 4 5 6 7 8 9
@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter {
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }
If you are using Spring Boot, it is recommended to just declare a WebMvcConfigurer bean as following:
1 2 3 4 5 6 7 8 9 10 11 12 13
@Configuration public class MyConfiguration {
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }; } }COPY
You can easily change any properties, as well as only apply this CORS configuration to a specific path pattern:
If you are using Spring Security, make sure to enable CORS at Spring Security level as well to allow it to leverage the configuration defined at Spring MVC level.
<http> <!-- Default to Spring MVC's CORS configuration --> <cors /> ... </http>
How does it work?
CORS requests (including preflight ones with an OPTIONS method) are automatically dispatched to the various HandlerMappings registered. They handle CORS preflight requests and intercept CORS simple and actual requests thanks to a CorsProcessor implementation (DefaultCorsProcessor by default) in order to add the relevant CORS response headers (like Access-Control-Allow-Origin). CorsConfiguration allows you to specify how the CORS requests should be processed: allowed origins, headers, methods, etc. It can be provided in various ways:
As an alternative to other methods presented above, Spring Framework also provides a CorsFilter. In that case, instead of using @CrossOrigin or WebMvcConfigurer#addCorsMappings(CorsRegistry), you can for example declare the filter as following in your Spring Boot application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@Configuration public class MyConfiguration {
@Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("http://domain1.com"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; } }
public class Rhymes { private static Random rnd = new Random();
public static void main(String[] args) { StringBuffer word = null; switch (rnd.nextInt(3)) { case 1: word = new StringBuffer("P"); break; case 2: word = new StringBuffer("G"); break; default: word = new StringBuffer("M"); break; } word.append('a'); word.append('i'); word.append('n'); System.out.println(word); } }