Polish
This commit is contained in:
parent
8295e82ea0
commit
2bb0f744e0
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -119,36 +119,13 @@ public enum EmbeddedDatabaseConnection {
|
|||
* @return true if the data sourceis one of the embedded types
|
||||
*/
|
||||
public static boolean isEmbedded(DataSource dataSource) {
|
||||
boolean embedded = false;
|
||||
try {
|
||||
embedded = new JdbcTemplate(dataSource)
|
||||
.execute(new ConnectionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInConnection(Connection con)
|
||||
throws SQLException, DataAccessException {
|
||||
String productName = con.getMetaData()
|
||||
.getDatabaseProductName();
|
||||
if (productName == null) {
|
||||
return false;
|
||||
}
|
||||
productName = productName.toUpperCase();
|
||||
if (productName.contains(H2.name())) {
|
||||
return true;
|
||||
}
|
||||
if (productName.contains(HSQL.name())) {
|
||||
return true;
|
||||
}
|
||||
if (productName.contains(DERBY.name())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return new JdbcTemplate(dataSource).execute(new IsEmbedded());
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
catch (DataAccessException ex) {
|
||||
// Could not connect, which means it's not embedded
|
||||
return false;
|
||||
}
|
||||
return embedded;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -170,4 +147,27 @@ public enum EmbeddedDatabaseConnection {
|
|||
return NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ConnectionCallback} to determine if a connection is embedded.
|
||||
*/
|
||||
private static class IsEmbedded implements ConnectionCallback<Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean doInConnection(Connection connection) throws SQLException,
|
||||
DataAccessException {
|
||||
String productName = connection.getMetaData().getDatabaseProductName();
|
||||
if (productName == null) {
|
||||
return false;
|
||||
}
|
||||
productName = productName.toUpperCase();
|
||||
EmbeddedDatabaseConnection[] candidates = EmbeddedDatabaseConnection.values();
|
||||
for (EmbeddedDatabaseConnection candidate : candidates) {
|
||||
if (candidate != NONE && productName.contains(candidate.name())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link JmsTemplate}.
|
||||
|
|
@ -64,25 +65,22 @@ public class JmsTemplateAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
public ConnectionFactory jmsConnectionFactory() {
|
||||
ConnectionFactory connectionFactory;
|
||||
if (this.config.getUser() != null && !"".equals(this.config.getUser())
|
||||
&& this.config.getPassword() != null
|
||||
&& !"".equals(this.config.getPassword())) {
|
||||
connectionFactory = new ActiveMQConnectionFactory(this.config.getUser(),
|
||||
this.config.getPassword(), this.config.getBrokerUrl());
|
||||
}
|
||||
else {
|
||||
connectionFactory = new ActiveMQConnectionFactory(
|
||||
this.config.getBrokerUrl());
|
||||
}
|
||||
ConnectionFactory connectionFactory = getActiveMQConnectionFactory();
|
||||
if (this.config.isPooled()) {
|
||||
PooledConnectionFactory pool = new PooledConnectionFactory();
|
||||
pool.setConnectionFactory(connectionFactory);
|
||||
return pool;
|
||||
}
|
||||
else {
|
||||
return connectionFactory;
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
private ConnectionFactory getActiveMQConnectionFactory() {
|
||||
if (StringUtils.hasLength(this.config.getUser())
|
||||
&& StringUtils.hasLength(this.config.getPassword())) {
|
||||
return new ActiveMQConnectionFactory(this.config.getUser(),
|
||||
this.config.getPassword(), this.config.getBrokerUrl());
|
||||
}
|
||||
return new ActiveMQConnectionFactory(this.config.getBrokerUrl());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -935,14 +935,14 @@ and {sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[`JpaBas
|
|||
for more details.
|
||||
|
||||
|
||||
|
||||
[[howto-use-custom-entity-manager]]
|
||||
=== Use a custom EntityManagerFactory
|
||||
To take full control of the configuration of the
|
||||
`EntityManagerFactory`, you need to add a `@Bean` named
|
||||
"entityManagerFactory". To avoid eager initialization of JPA
|
||||
infrastructure Spring Boot autoconfiguration does not switch on its
|
||||
entity manager based on the presence of a bean of that type. Instead
|
||||
it has to do it by name.
|
||||
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
||||
a `@Bean` named "entityManagerFactory". To avoid eager initialization of JPA
|
||||
infrastructure, Spring Boot auto-configuration does not switch on its entity manager
|
||||
based on the presence of a bean of that type. Instead it has to do it by name.
|
||||
|
||||
|
||||
|
||||
[[howto-use-traditional-persistence-xml]]
|
||||
|
|
@ -1140,9 +1140,12 @@ use this in a webapp is to inject it into a void method in a
|
|||
}
|
||||
----
|
||||
|
||||
You will get the best results if you put this in a nested class, or a standalone class (i.e.
|
||||
not mixed in with a lot of other `@Beans` that might be allowed to influence the order of
|
||||
instantiation). The https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-secure[secure web sample] is a useful template to follow.
|
||||
You will get the best results if you put this in a nested class, or a standalone class
|
||||
(i.e. not mixed in with a lot of other `@Beans` that might be allowed to influence the
|
||||
order of instantiation). The {github-code}/spring-boot-samples/spring-boot-sample-web-secure[secure web sample]
|
||||
is a useful template to follow.
|
||||
|
||||
|
||||
|
||||
[[howto-enable-https]]
|
||||
=== Enable HTTPS
|
||||
|
|
|
|||
|
|
@ -251,8 +251,8 @@ all non-sensitive endpoints to be exposed over HTTP. The default convention is t
|
|||
|
||||
[[production-ready-sensitive-endpoints]]
|
||||
=== Exposing sensitive endpoints
|
||||
If you use ``Spring Security'' sensitive endpoints will be exposed over HTTP, but also
|
||||
protected. By default ``basic'' authentication will be used with the username `user`
|
||||
If you use ``Spring Security'' sensitive endpoints will be exposed over HTTP, but also
|
||||
protected. By default ``basic'' authentication will be used with the username `user`
|
||||
and a generated password (which is printed on the console when the application starts).
|
||||
|
||||
TIP: Generated passwords are logged as the application starts. Search for ``Using default
|
||||
|
|
@ -300,11 +300,10 @@ The `management.port` property can be used to change the HTTP port.
|
|||
management.port=8081
|
||||
----
|
||||
|
||||
Since your management
|
||||
port is often protected by a firewall, and not exposed to the public you might not need
|
||||
security on the management endpoints, even if your main application is secure. In that
|
||||
case you will have Spring
|
||||
Security on the classpath, and you can disable management security like this:
|
||||
Since your management port is often protected by a firewall, and not exposed to the public
|
||||
you might not need security on the management endpoints, even if your main application is
|
||||
secure. In that case you will have Spring Security on the classpath, and you can disable
|
||||
management security like this:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
|
|
@ -314,6 +313,8 @@ Security on the classpath, and you can disable management security like this:
|
|||
(If you don't have Spring Security on the classpath then there is no need to explicitly
|
||||
disable the management security in this way, and it might even break the application.)
|
||||
|
||||
|
||||
|
||||
[[production-ready-customizing-management-server-address]]
|
||||
=== Customizing the management server address
|
||||
You can customize the address that the management endpoints are available on by
|
||||
|
|
|
|||
|
|
@ -993,6 +993,8 @@ packaged as an executable archive), there are some limitations in the JSP suppor
|
|||
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so
|
||||
you can see how to set things up.
|
||||
|
||||
|
||||
|
||||
[[boot-features-security]]
|
||||
== Security
|
||||
If Spring Security is on the classpath then web applications will be secure by default
|
||||
|
|
@ -1001,58 +1003,47 @@ application you can also add `@EnableGlobalMethodSecurity` with your desired set
|
|||
Additional information can be found in the {spring-security-reference}#jc-method[Spring
|
||||
Security Reference].
|
||||
|
||||
The default `AuthenticationManager` has a single user (username
|
||||
``user'' and password random, printed at INFO level when the
|
||||
application starts up). You can change the password by providing a
|
||||
`security.user.password`. This and other useful properties are
|
||||
externalized via
|
||||
{sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
|
||||
The default `AuthenticationManager` has a single user (username ``user'' and password
|
||||
random, printed at INFO level when the application starts up). You can change the
|
||||
password by providing a `security.user.password`. This and other useful properties are
|
||||
externalized via {sc-spring-boot-autoconfigure}/security/SecurityProperties.{sc-ext}[`SecurityProperties`]
|
||||
(properties prefix "security").
|
||||
|
||||
The default security configuration is implemented in
|
||||
`SecurityAutoConfiguration` and in the classes imported from there
|
||||
(`SpringBootWebSecurityConfiguration` for web security and
|
||||
`AuthenticationManagerConfiguration` for authentication configuration
|
||||
which is also relevant in non-web applications). To switch off the
|
||||
Boot default configuration completely in a web application you can add
|
||||
a bean with `@EnableWebSecurity`. To customize it you normally use
|
||||
external properties and beans of type `WebConfigurerAdapter` (e.g. to
|
||||
The default security configuration is implemented in `SecurityAutoConfiguration` and in
|
||||
the classes imported from there (`SpringBootWebSecurityConfiguration` for web security
|
||||
and `AuthenticationManagerConfiguration` for authentication configuration which is also
|
||||
relevant in non-web applications). To switch off the Boot default configuration
|
||||
completely in a web application you can add a bean with `@EnableWebSecurity`. To customize
|
||||
it you normally use external properties and beans of type `WebConfigurerAdapter` (e.g. to
|
||||
add form-based login). There are several secure applications in the
|
||||
{github-code}/spring-boot-samples/[Spring Boot samples] to get you
|
||||
started with common use cases.
|
||||
{github-code}/spring-boot-samples/[Spring Boot samples] to get you started with common
|
||||
use cases.
|
||||
|
||||
The basic features you get out of the box in a web application are
|
||||
|
||||
* An `AuthenticationManager` bean with in-memory store and a single
|
||||
user (see `SecurityProperties.User` for the properties of the user).
|
||||
|
||||
* Ignored (unsecure) paths for common static resource locations
|
||||
(`/css/**`, `/js/**`, `/images/**` and `**/favicon.ico`).
|
||||
The basic features you get out of the box in a web application are:
|
||||
|
||||
* An `AuthenticationManager` bean with in-memory store and a single user (see
|
||||
`SecurityProperties.User` for the properties of the user).
|
||||
* Ignored (unsecure) paths for common static resource locations (`/css/**`, `/js/**`,
|
||||
`/images/**` and `**/favicon.ico`).
|
||||
* HTTP Basic security for all other endpoints.
|
||||
* Security events published to Spring's `ApplicationEventPublisher` (successful and
|
||||
unsuccessful authentication and access denied).
|
||||
* Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are
|
||||
on by default.
|
||||
|
||||
* Security events published to Spring's `ApplicationEventPublisher`
|
||||
(successful and unsuccessful authentication and access denied).
|
||||
|
||||
* Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring
|
||||
Security are on by default.
|
||||
|
||||
All of the above can be switched on and off or modified using external
|
||||
properties (`security.*`).
|
||||
All of the above can be switched on and off or modified using external properties
|
||||
(`security.*`).
|
||||
|
||||
If the Actuator is also in use, you will find:
|
||||
|
||||
* The management endpoints are secure even if the application
|
||||
endpoints are unsecure.
|
||||
* The management endpoints are secure even if the application endpoints are unsecure.
|
||||
* Security events are transformed into `AuditEvents` and published to the `AuditService`.
|
||||
* The default user will have the "ADMIN" role as well as the "USER" role.
|
||||
|
||||
* Security events are transformed into `AuditEvents` and published to
|
||||
the `AuditService`.
|
||||
The Actuator security features can be modified using external properties
|
||||
(`management.security.*`).
|
||||
|
||||
* The default user will have the "ADMIN" role as well as the "USER"
|
||||
role.
|
||||
|
||||
The Actuator security features can be modified using external
|
||||
properties (`management.security.*`).
|
||||
|
||||
[[boot-features-sql]]
|
||||
== Working with SQL databases
|
||||
|
|
@ -1299,12 +1290,12 @@ following to your `application.properties`.
|
|||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
----
|
||||
|
||||
Note that Hibernate's own internal property name for this (if you
|
||||
happen to remember it better) is `hibernate.hbm2ddl.auto`. You can set
|
||||
it, along with other Hibernate native properties, using
|
||||
`spring.jpa.properties.*` (the prefix is stripped before adding them
|
||||
to the entity manager). Also relevant:
|
||||
`spring.jpa.generate-ddl=false` switches off all DDL generation.
|
||||
NOTE: Hibernate's own internal property name for this (if you happen to remember it
|
||||
better) is `hibernate.hbm2ddl.auto`. You can set it, along with other Hibernate native
|
||||
properties, using `spring.jpa.properties.*` (the prefix is stripped before adding them
|
||||
to the entity manager). Alternatively, `spring.jpa.generate-ddl=false` switches off all
|
||||
DDL generation.
|
||||
|
||||
|
||||
|
||||
[[boot-features-nosql]]
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import org.springframework.boot.loader.tools.MainClassFinder;
|
|||
|
||||
/**
|
||||
* Run the project from Gradle.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RunApp extends DefaultTask {
|
||||
|
|
@ -75,7 +75,7 @@ public class RunApp extends DefaultTask {
|
|||
}
|
||||
if (outputDir != null) {
|
||||
for (File directory : allResources) {
|
||||
FileUtils.removeDuplicatesFromCopy(outputDir, directory);
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(outputDir, directory);
|
||||
}
|
||||
}
|
||||
exec.exec();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* originright 2012-2013 the copyal author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a origin of the License at
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
|
|
@ -26,24 +26,24 @@ import java.io.File;
|
|||
public class FileUtils {
|
||||
|
||||
/**
|
||||
* Utility to remove duplicate files from a "copy" directory if they already exist in
|
||||
* an "origin". Recursively scans the origin directory looking for files (not
|
||||
* Utility to remove duplicate files from an "output" directory if they already exist
|
||||
* in an "origin". Recursively scans the origin directory looking for files (not
|
||||
* directories) that exist in both places and deleting the copy.
|
||||
*
|
||||
* @param copy the copy directory
|
||||
* @param origin the origin directory
|
||||
* @param outputDirectory the output directory
|
||||
* @param originDirectory the origin directory
|
||||
*/
|
||||
public static void removeDuplicatesFromCopy(File copy, File origin) {
|
||||
if (origin.isDirectory()) {
|
||||
for (String name : origin.list()) {
|
||||
File targetFile = new File(copy, name);
|
||||
public static void removeDuplicatesFromOutputDirectory(File outputDirectory,
|
||||
File originDirectory) {
|
||||
if (originDirectory.isDirectory()) {
|
||||
for (String name : originDirectory.list()) {
|
||||
File targetFile = new File(outputDirectory, name);
|
||||
if (targetFile.exists() && targetFile.canWrite()) {
|
||||
if (!targetFile.isDirectory()) {
|
||||
targetFile.delete();
|
||||
}
|
||||
else {
|
||||
FileUtils.removeDuplicatesFromCopy(targetFile, new File(origin,
|
||||
name));
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(targetFile,
|
||||
new File(originDirectory, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -27,60 +27,67 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests fir {@link FileUtils}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class FileUtilsTests {
|
||||
|
||||
private File origin;
|
||||
private File target;
|
||||
private File outputDirectory;
|
||||
|
||||
private File originDirectory;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.origin = new File("target/test/remove");
|
||||
this.target = new File("target/test/keep");
|
||||
FileSystemUtils.deleteRecursively(this.origin);
|
||||
FileSystemUtils.deleteRecursively(this.target);
|
||||
this.origin.mkdirs();
|
||||
this.target.mkdirs();
|
||||
this.outputDirectory = new File("target/test/remove");
|
||||
this.originDirectory = new File("target/test/keep");
|
||||
FileSystemUtils.deleteRecursively(this.outputDirectory);
|
||||
FileSystemUtils.deleteRecursively(this.originDirectory);
|
||||
this.outputDirectory.mkdirs();
|
||||
this.originDirectory.mkdirs();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleDuplicateFile() throws IOException {
|
||||
File file = new File(this.origin, "logback.xml");
|
||||
File file = new File(this.outputDirectory, "logback.xml");
|
||||
file.createNewFile();
|
||||
new File(this.target, "logback.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
|
||||
new File(this.originDirectory, "logback.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
|
||||
this.originDirectory);
|
||||
assertFalse(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedDuplicateFile() throws IOException {
|
||||
assertTrue(new File(this.origin, "sub").mkdirs());
|
||||
assertTrue(new File(this.target, "sub").mkdirs());
|
||||
File file = new File(this.origin, "sub/logback.xml");
|
||||
assertTrue(new File(this.outputDirectory, "sub").mkdirs());
|
||||
assertTrue(new File(this.originDirectory, "sub").mkdirs());
|
||||
File file = new File(this.outputDirectory, "sub/logback.xml");
|
||||
file.createNewFile();
|
||||
new File(this.target, "sub/logback.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
|
||||
new File(this.originDirectory, "sub/logback.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
|
||||
this.originDirectory);
|
||||
assertFalse(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedNonDuplicateFile() throws IOException {
|
||||
assertTrue(new File(this.origin, "sub").mkdirs());
|
||||
assertTrue(new File(this.target, "sub").mkdirs());
|
||||
File file = new File(this.origin, "sub/logback.xml");
|
||||
assertTrue(new File(this.outputDirectory, "sub").mkdirs());
|
||||
assertTrue(new File(this.originDirectory, "sub").mkdirs());
|
||||
File file = new File(this.outputDirectory, "sub/logback.xml");
|
||||
file.createNewFile();
|
||||
new File(this.target, "sub/different.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
|
||||
new File(this.originDirectory, "sub/different.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
|
||||
this.originDirectory);
|
||||
assertTrue(file.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonDuplicateFile() throws IOException {
|
||||
File file = new File(this.origin, "logback.xml");
|
||||
File file = new File(this.outputDirectory, "logback.xml");
|
||||
file.createNewFile();
|
||||
new File(this.target, "different.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromCopy(this.origin, this.target);
|
||||
new File(this.originDirectory, "different.xml").createNewFile();
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(this.outputDirectory,
|
||||
this.originDirectory);
|
||||
assertTrue(file.exists());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ public class RunMojo extends AbstractMojo {
|
|||
for (Resource resource : this.project.getResources()) {
|
||||
File directory = new File(resource.getDirectory());
|
||||
urls.add(directory.toURI().toURL());
|
||||
FileUtils.removeDuplicatesFromCopy(this.classesDirectory, directory);
|
||||
FileUtils.removeDuplicatesFromOutputDirectory(this.classesDirectory, directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
|||
Loading…
Reference in New Issue