├── .github └── workflows │ └── maven-build.yml ├── .gitignore ├── pom.xml ├── readme.md └── src ├── main ├── java │ └── com │ │ └── javaetmoi │ │ └── sample │ │ └── config │ │ ├── DataSourceConfig.java │ │ ├── InfrastructureConfig.java │ │ ├── MainConfig.java │ │ ├── RepositoryConfig.java │ │ ├── SecurityConfig.java │ │ ├── ServiceConfig.java │ │ └── WebMvcConfig.java ├── resources │ ├── com │ │ └── javaetmoi │ │ │ └── sample │ │ │ └── config │ │ │ ├── datasource.properties │ │ │ └── infrastructure.properties │ └── jndi.properties └── webapp │ └── WEB-INF │ ├── jetty-web.xml │ └── web.xml └── test └── java └── com └── javaetmoi └── sample └── config └── SpringConfigTest.java /.github/workflows/maven-build.yml: -------------------------------------------------------------------------------- 1 | name: Java CI with Maven 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Set up JDK 17 17 | uses: actions/setup-java@v4 18 | with: 19 | java-version: '17' 20 | distribution: 'adopt' 21 | cache: maven 22 | - name: Build with Maven 23 | run: mvn -B package -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse files 2 | .project 3 | .classpath 4 | .settings 5 | 6 | # Compiled classes 7 | target 8 | 9 | .DS_Store 10 | 11 | # Idea IntelliJ 12 | .idea 13 | *.iml -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.javaetmoi.core 7 | spring-javaconfig-sample 8 | JavaEtMoi Core :: ${project.artifactId} - ${project.packaging} 9 | 1.0.0-SNAPSHOT 10 | war 11 | Spring JavaConfig example for Spring MVC / Spring Data JPA / Hibernate 12 | 2014 13 | https://github.com/arey/spring-javaconfig-sample 14 | 15 | 16 | 17 | https://github.com/arey/spring-javaconfig-sample 18 | scm:git:ssh://git@github.com/arey/spring-javaconfig-sample.git 19 | scm:git:ssh://git@github.com/arey/spring-javaconfig-sample.git 20 | 21 | 22 | 23 | 24 | 25 | Apache License, Version 2.0 26 | http://www.apache.org/licenses/LICENSE-2.0 27 | 28 | 29 | 30 | 31 | 17 32 | 33 | 34 | 6.2.1 35 | 3.4.1 36 | 6.4.2 37 | 6.1.0 38 | 6.6.4.Final 39 | 3.30.2-GA 40 | 3.1.0 41 | 1.9.22.1 42 | 1.5.15 43 | 2.0.16 44 | 2.3.232 45 | 5.11.4 46 | 12.0.15 47 | 1.4 48 | 49 | 50 | 2.9 51 | 3.13.0 52 | 3.1.0 53 | 3.2.1 54 | 3.11.2 55 | 2.2.2 56 | 3.1.3 57 | 3.4.0 58 | 59 | 60 | 1.0-beta-2 61 | 62 | 63 | 64 | UTF-8 65 | 66 | 67 | 68 | 69 | 70 | org.springframework 71 | spring-webmvc 72 | ${version.spring-framework} 73 | 74 | 75 | org.springframework 76 | spring-jdbc 77 | ${version.spring-framework} 78 | 79 | 80 | org.springframework 81 | spring-orm 82 | ${version.spring-framework} 83 | 84 | 85 | org.springframework 86 | spring-expression 87 | ${version.spring-framework} 88 | 89 | 90 | org.springframework 91 | spring-test 92 | ${version.spring-framework} 93 | test 94 | 95 | 96 | 97 | 98 | 99 | jakarta.servlet 100 | jakarta.servlet-api 101 | ${version.servlet-api} 102 | 103 | 104 | 105 | 106 | 107 | jakarta.persistence 108 | jakarta.persistence-api 109 | ${jakarta.persistence-api.version} 110 | 111 | 112 | 113 | 114 | org.hibernate 115 | hibernate-core 116 | ${version.hibernate} 117 | 118 | 119 | 120 | org.javassist 121 | javassist 122 | ${version.hibernate-javassist} 123 | 124 | 125 | 126 | 127 | org.springframework.data 128 | spring-data-jpa 129 | ${version.spring-data-jpa} 130 | 131 | 132 | 133 | 134 | org.springframework.security 135 | spring-security-web 136 | ${version.spring-security} 137 | 138 | 139 | org.springframework.security 140 | spring-security-config 141 | ${version.spring-security} 142 | 143 | 144 | 145 | 146 | org.aspectj 147 | aspectjweaver 148 | ${version.aspectj} 149 | 150 | 151 | 152 | 153 | ch.qos.logback 154 | logback-classic 155 | ${version.logback} 156 | 157 | 158 | org.slf4j 159 | jcl-over-slf4j 160 | ${version.slf4j} 161 | 162 | 163 | 164 | 165 | com.h2database 166 | h2 167 | ${version.h2} 168 | 169 | 170 | 171 | 172 | org.junit.jupiter 173 | junit-jupiter-engine 174 | ${version.junit} 175 | test 176 | 177 | 178 | 179 | 180 | org.eclipse.jetty 181 | jetty-plus 182 | ${version.jetty} 183 | runtime 184 | 185 | 186 | commons-dbcp 187 | commons-dbcp 188 | ${version.commons-dbcp} 189 | runtime 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | org.apache.maven.wagon 198 | wagon-webdav 199 | ${version.extension.wagon-webdav} 200 | 201 | 202 | 203 | 204 | 205 | org.apache.maven.plugins 206 | maven-compiler-plugin 207 | ${version.plugin.maven-compiler-plugin} 208 | 209 | ${version.java} 210 | ${version.java} 211 | 212 | 213 | 214 | org.apache.maven.plugins 215 | maven-resources-plugin 216 | ${version.plugin.maven-resources-plugin} 217 | 218 | 219 | org.apache.maven.plugins 220 | maven-source-plugin 221 | ${version.plugin.maven-source-plugin} 222 | 223 | 224 | org.apache.maven.plugins 225 | maven-release-plugin 226 | ${version.plugin.maven-release-plugin} 227 | 228 | 229 | org.apache.maven.plugins 230 | maven-javadoc-plugin 231 | ${version.plugin.maven-javadoc-plugin} 232 | 233 | 234 | org.apache.maven.plugins 235 | maven-deploy-plugin 236 | ${version.plugin.maven-deploy-plugin} 237 | 238 | 239 | org.apache.maven.plugins 240 | maven-war-plugin 241 | ${maven-war-plugin.version} 242 | 243 | 244 | 245 | org.eclipse.jetty.ee10 246 | jetty-ee10-maven-plugin 247 | ${version.jetty} 248 | 249 | 10 250 | foo 251 | 9999 252 | 253 | 254 | 255 | start-jetty 256 | pre-integration-test 257 | 258 | run-war 259 | 260 | 261 | 0 262 | true 263 | 264 | 265 | 266 | stop-jetty 267 | post-integration-test 268 | 269 | stop 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | https://github.com/arey/spring-javaconfig-sample 280 | 281 | javaetmoi-cloudbees-release 282 | javaetmoi-cloudbees-release 283 | dav:https://repository-javaetmoi.forge.cloudbees.com/release/ 284 | 285 | 286 | javaetmoi-cloudbees-snapshot 287 | javaetmoi-cloudbees-snapshot 288 | dav:https://repository-javaetmoi.forge.cloudbees.com/snapshot/ 289 | 290 | 291 | 292 | 293 | 294 | javaetmoi-cloudbees-release 295 | javaetmoi-cloudbees-release 296 | https://repository-javaetmoi.forge.cloudbees.com/release/ 297 | 298 | true 299 | 300 | 301 | false 302 | 303 | 304 | 305 | javaetmoi-cloudbees-snapshot 306 | javaetmoi-cloudbees-snapshot 307 | https://repository-javaetmoi.forge.cloudbees.com/snapshot/ 308 | 309 | false 310 | 311 | 312 | true 313 | 314 | 315 | 316 | 317 | 318 | 319 | eclipse 320 | 321 | true 322 | 323 | 324 | 325 | 326 | 327 | maven-eclipse-plugin 328 | ${version.plugin.maven-eclipse-plugin} 329 | 330 | 2.0 331 | true 332 | true 333 | none 334 | true 335 | 336 | org.springframework.ide.eclipse.core.springnature 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | release 349 | 350 | 351 | 352 | org.apache.maven.plugins 353 | maven-source-plugin 354 | 355 | 356 | attach-sources 357 | 358 | jar 359 | 360 | 361 | 362 | 363 | 364 | org.apache.maven.plugins 365 | maven-javadoc-plugin 366 | 367 | 368 | attach-sources 369 | 370 | jar 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Spring Java Config Sample # 2 | [![Build Status](https://github.com/arey/spring-javaconfig-sample/actions/workflows/maven-build.yml/badge.svg)](https://github.com/arey/spring-javaconfig-sample/actions/workflows/maven-build.yml) 3 | 4 | Since Spring Framework 3.0, the JavaConfig features are included in the Core Spring module. Thus Java Developer could move Spring beans definition from configuration XML files to Java classes. 5 | 6 | Based on Spring Framework 6.2, Spring Data JPA 3.4, Spring Security 6.4 and Hibernate ORM 6.6, this sample show how to use the Spring's new Java-configuration support and its @Configuration-annotated class. 7 | 8 | The following classes, interfaces and annotations are used in the sample: 9 | * JavaConfig main classes and annotations: `@Configuration`, `@Bean`, `@ComponentScan`, `@Import`, `@ImportResource`, `@Profile`, `Environment`, `JndiObjectFactoryBean`, `@Scope` 10 | * Spring Test: `@WebAppConfiguration`, `@ContextConfiguration`, `@ActiveProfiles`, `@ContextHierarchy` 11 | * Advanced Spring Framework features: `@EnableTransactionManagement`, `@EnableAsync`, `@EnableCaching`, `@EnableAspectJAutoProxy` 12 | * Spring Data JPA annotations: `@EnableJpaRepositories` 13 | * Spring Security classes: `@EnableWebMvcSecurity`, `WebSecurityConfigurerAdapter` 14 | * Spring MVC features: `@EnableWebMvc`, `WebMvcConfigurerAdapter`, `RequestMappingHandlerAdapter`, `InternalResourceViewResolver`, `ignoreDefaultModelOnRedirect` 15 | 16 | 17 | ## Quick start ## 18 | 19 | Download the code with git: 20 | ``` 21 | git clone git://github.com/arey/spring-javaconfig-sample.git 22 | ``` 23 | 24 | Compile the code with maven: 25 | ``` 26 | mvn clean install 27 | ``` 28 | 29 | If you're using an IDE that supports Maven-based projects (InteliJ Idea, Netbeans or m2Eclipse), you can import the project directly from its POM. 30 | Otherwise, generate IDE metadata with the related IDE maven plugin: 31 | ``` 32 | mvn eclipse:clean eclipse:eclipse 33 | ``` 34 | 35 | ## Documentation ## 36 | 37 | French articles on the [javaetmoi.com](http://javaetmoi.com) blog: 38 | 39 | * [Configurez Spring en Java](http://javaetmoi.com/2014/06/spring-framework-java-configuration/) 40 | 41 | ## Credits ## 42 | 43 | * Uses [Maven](http://maven.apache.org/) as a build tool 44 | * Uses GitHub Actions for continuous integration builds 45 | 46 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | import javax.sql.DataSource; 16 | 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.context.annotation.Profile; 21 | import org.springframework.context.annotation.PropertySource; 22 | import org.springframework.core.env.Environment; 23 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; 24 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; 25 | import org.springframework.jndi.JndiObjectFactoryBean; 26 | 27 | /** 28 | * Depending active spring profile, lookup RDBMS DataSource from JNDI or from an embbeded H2 database. 29 | */ 30 | @Configuration 31 | @PropertySource({ "classpath:com/javaetmoi/sample/config/datasource.properties" }) 32 | public class DataSourceConfig { 33 | 34 | @Autowired 35 | private Environment env; 36 | 37 | @Bean 38 | @Profile("javaee") 39 | public JndiObjectFactoryBean dataSource() throws IllegalArgumentException { 40 | JndiObjectFactoryBean dataSource = new JndiObjectFactoryBean(); 41 | dataSource.setExpectedType(DataSource.class); 42 | dataSource.setJndiName(env.getProperty("jdbc.jndiDataSource")); 43 | return dataSource; 44 | } 45 | 46 | @Bean 47 | @Profile("test") 48 | public DataSource testDataSource() { 49 | return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/InfrastructureConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import java.util.HashMap; 17 | import java.util.Map; 18 | 19 | import jakarta.persistence.EntityManagerFactory; 20 | import javax.sql.DataSource; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.context.annotation.PropertySource; 26 | import org.springframework.core.env.Environment; 27 | import org.springframework.orm.jpa.JpaTransactionManager; 28 | import org.springframework.orm.jpa.JpaVendorAdapter; 29 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 30 | import org.springframework.orm.jpa.vendor.Database; 31 | import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 32 | import org.springframework.transaction.annotation.EnableTransactionManagement; 33 | import org.springframework.transaction.support.TransactionTemplate; 34 | 35 | @Configuration 36 | @EnableTransactionManagement 37 | @PropertySource({ "classpath:com/javaetmoi/sample/config/infrastructure.properties" }) 38 | public class InfrastructureConfig { 39 | 40 | @Autowired 41 | Environment env; 42 | 43 | @Autowired 44 | private DataSource dataSource; 45 | 46 | 47 | @Bean 48 | public JpaTransactionManager transactionManager() { 49 | JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); 50 | jpaTransactionManager.setEntityManagerFactory(entityManagerFactory()); 51 | return jpaTransactionManager; 52 | } 53 | 54 | @Bean 55 | public TransactionTemplate transactionTemplate() { 56 | TransactionTemplate transactionTemplate = new TransactionTemplate(); 57 | transactionTemplate.setTransactionManager(transactionManager()); 58 | return transactionTemplate; 59 | } 60 | 61 | @Bean 62 | public EntityManagerFactory entityManagerFactory() { 63 | LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 64 | em.setDataSource(dataSource); 65 | em.setPersistenceUnitName("javaconfigSamplePersistenceUnit"); 66 | em.setPackagesToScan("com.javaetmoi.sample.domain"); 67 | em.setJpaVendorAdapter(jpaVendorAdaper()); 68 | em.setJpaPropertyMap(additionalProperties()); 69 | em.afterPropertiesSet(); 70 | return em.getObject(); 71 | } 72 | 73 | @Bean 74 | public JpaVendorAdapter jpaVendorAdaper() { 75 | HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 76 | vendorAdapter.setDatabase(env.getProperty("jpa.database", Database.class)); 77 | vendorAdapter.setShowSql(env.getProperty("jpa.showSql", Boolean.class)); 78 | vendorAdapter.setGenerateDdl(env.getProperty("jpa.generateDdl", Boolean.class)); 79 | return vendorAdapter; 80 | } 81 | 82 | private Map additionalProperties() { 83 | Map properties = new HashMap(); 84 | properties.put("hibernate.validator.apply_to_ddl", "false"); 85 | properties.put("hibernate.validator.autoregister_listeners", "false"); 86 | properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); 87 | properties.put("hibernate.generate_statistics", env.getProperty("hibernate.generate_statistics")); 88 | // Second level cache configuration and so on. 89 | return properties; 90 | } 91 | 92 | 93 | } -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/MainConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import jakarta.annotation.PostConstruct; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.context.annotation.Import; 23 | import org.springframework.core.env.Environment; 24 | 25 | /** 26 | * Configuration of the business, persistence and security layers. 27 | */ 28 | @Configuration 29 | @Import(value = { 30 | DataSourceConfig.class, 31 | InfrastructureConfig.class, 32 | RepositoryConfig.class, 33 | ServiceConfig.class, 34 | SecurityConfig.class 35 | } ) 36 | public class MainConfig { 37 | 38 | private static final Logger LOG = LoggerFactory.getLogger(MainConfig.class); 39 | 40 | @Autowired 41 | private Environment env; 42 | 43 | /** 44 | * Application custom initialization code. 45 | *

46 | * Spring profiles can be configured with a system property 47 | * -Dspring.profiles.active=javaee 48 | *

49 | */ 50 | @PostConstruct 51 | public void initApp() { 52 | LOG.debug("Looking for Spring profiles..."); 53 | if (env.getActiveProfiles().length == 0) { 54 | LOG.info("No Spring profile configured, running with default configuration."); 55 | } else { 56 | for (String profile : env.getActiveProfiles()) { 57 | LOG.info("Detected Spring profile: {}", profile); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/RepositoryConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 17 | 18 | /** 19 | * Enable and scan Spring Data repositories. 20 | * 21 | */ 22 | @Configuration 23 | @EnableJpaRepositories("com.javaetmoi.sample.repository") 24 | public class RepositoryConfig { 25 | // 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.context.annotation.Bean; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.context.annotation.Scope; 20 | import org.springframework.context.annotation.ScopedProxyMode; 21 | import org.springframework.security.authentication.RememberMeAuthenticationToken; 22 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 23 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 24 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 25 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 26 | import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; 27 | import org.springframework.security.core.Authentication; 28 | import org.springframework.security.core.context.SecurityContextHolder; 29 | import org.springframework.security.core.userdetails.UserDetails; 30 | import org.springframework.security.web.SecurityFilterChain; 31 | import org.springframework.web.servlet.handler.HandlerMappingIntrospector; 32 | 33 | 34 | @Configuration 35 | @EnableWebSecurity 36 | public class SecurityConfig { 37 | 38 | 39 | @Autowired 40 | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 41 | // to customize with your own authentication provider 42 | auth 43 | .inMemoryAuthentication() 44 | .withUser("user").password("password").roles("USER"); 45 | } 46 | 47 | @Bean 48 | public WebSecurityCustomizer webSecurityCustomizer() { 49 | return (web) -> web.ignoring().requestMatchers("/resources/**"); 50 | } 51 | 52 | 53 | @Bean 54 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 55 | http 56 | .authorizeHttpRequests((authz) -> authz 57 | .requestMatchers("/signup","/about").permitAll() 58 | .requestMatchers("/admin/**").hasRole("ADMIN") 59 | .anyRequest().authenticated()) 60 | .formLogin(form -> form 61 | .loginPage("/login") 62 | .permitAll() 63 | ); 64 | return http.build(); 65 | } 66 | 67 | 68 | /** 69 | * Authenticated user information available as a proxified Spring bean. 70 | * 71 | *

Could be inject into beans of scope singleton (ie. @Service or @Controller) 72 | */ 73 | @Bean 74 | @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 75 | public UserDetails authenticatedUserDetails() { 76 | SecurityContextHolder.getContext().getAuthentication(); 77 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 78 | if (authentication != null) { 79 | if (authentication instanceof UsernamePasswordAuthenticationToken) { 80 | return (UserDetails) authentication.getPrincipal(); 81 | } 82 | if (authentication instanceof RememberMeAuthenticationToken) { 83 | return (UserDetails) authentication.getPrincipal(); 84 | } 85 | } 86 | return null; 87 | } 88 | 89 | @Bean 90 | public HandlerMappingIntrospector mvcHandlerMappingIntrospector() { 91 | return new HandlerMappingIntrospector(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/ServiceConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.concurrent.Executor; 19 | 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 23 | import org.springframework.cache.Cache; 24 | import org.springframework.cache.CacheManager; 25 | import org.springframework.cache.annotation.EnableCaching; 26 | import org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean; 27 | import org.springframework.cache.support.SimpleCacheManager; 28 | import org.springframework.context.annotation.Bean; 29 | import org.springframework.context.annotation.ComponentScan; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 32 | import org.springframework.scheduling.annotation.AsyncConfigurer; 33 | import org.springframework.scheduling.annotation.EnableAsync; 34 | import org.springframework.scheduling.annotation.EnableScheduling; 35 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 36 | 37 | @Configuration 38 | @EnableAsync 39 | @EnableScheduling 40 | @EnableAspectJAutoProxy 41 | @EnableCaching 42 | @ComponentScan(basePackages = { "com.javaetmoi.sample.service" }) 43 | public class ServiceConfig implements AsyncConfigurer { 44 | 45 | private final Logger log = LoggerFactory.getLogger(ServiceConfig.class); 46 | 47 | @Bean 48 | public CacheManager cacheManager() { 49 | SimpleCacheManager cacheManager = new SimpleCacheManager(); 50 | List caches = new ArrayList(); 51 | // to customize 52 | caches.add(defaultCache()); 53 | cacheManager.setCaches(caches); 54 | return cacheManager; 55 | } 56 | 57 | @Bean 58 | public Cache defaultCache() { 59 | ConcurrentMapCacheFactoryBean cacheFactoryBean = new ConcurrentMapCacheFactoryBean(); 60 | cacheFactoryBean.setName("default"); 61 | cacheFactoryBean.afterPropertiesSet(); 62 | return cacheFactoryBean.getObject(); 63 | 64 | } 65 | 66 | @Override 67 | public Executor getAsyncExecutor() { 68 | log.debug("Creating Async Task Executor"); 69 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 70 | // to customize with your requirements 71 | executor.setCorePoolSize(5); 72 | executor.setMaxPoolSize(40); 73 | executor.setQueueCapacity(100); 74 | executor.setThreadNamePrefix("MyExecutor-"); 75 | executor.initialize(); 76 | return executor; 77 | } 78 | 79 | @Override 80 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 81 | // You may customize the handler that manages exceptions thrown during an asynchronous method execution 82 | // See http://www.concretepage.com/spring-4/spring-4-async-exception-handling-with-asyncuncaughtexceptionhandler 83 | return null; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/javaetmoi/sample/config/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import jakarta.annotation.PostConstruct; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.ComponentScan; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.context.support.ReloadableResourceBundleMessageSource; 23 | import org.springframework.format.FormatterRegistry; 24 | import org.springframework.web.servlet.ViewResolver; 25 | import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; 26 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 27 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 28 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 29 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 30 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 31 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 32 | import org.springframework.web.servlet.view.JstlView; 33 | 34 | @Configuration 35 | @EnableWebMvc 36 | @ComponentScan(basePackages = {"com.javaetmoi.sample.web"}) 37 | public class WebMvcConfig implements WebMvcConfigurer { 38 | 39 | private static final int CACHE_PERIOD = 31556926; // one year 40 | 41 | @Autowired 42 | private RequestMappingHandlerAdapter requestMappingHandlerAdapter; 43 | 44 | @PostConstruct 45 | public void init() { 46 | requestMappingHandlerAdapter.setIgnoreDefaultModelOnRedirect(true); 47 | } 48 | 49 | @Bean 50 | public ViewResolver viewResolver() { 51 | // Example: the 'info' view logical name is mapped to the file '/WEB-INF/jsp/info.jsp' 52 | InternalResourceViewResolver bean = new InternalResourceViewResolver(); 53 | bean.setViewClass(JstlView.class); 54 | bean.setPrefix("/WEB-INF/jsp/"); 55 | bean.setSuffix(".jsp"); 56 | return bean; 57 | } 58 | 59 | @Bean(name = "messageSource") 60 | public ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource() { 61 | ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); 62 | messageSource.setBasenames("classpath:com/javaetmoi/sample/web/messages"); 63 | messageSource.setDefaultEncoding("UTF-8"); 64 | return messageSource; 65 | } 66 | 67 | @Override 68 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 69 | // Static ressources from both WEB-INF and webjars 70 | registry 71 | .addResourceHandler("/resources/**") 72 | .addResourceLocations("/resources/") 73 | .setCachePeriod(CACHE_PERIOD); 74 | registry 75 | .addResourceHandler("/webjars/**") 76 | .addResourceLocations("classpath:/META-INF/resources/webjars/") 77 | .setCachePeriod(CACHE_PERIOD); 78 | } 79 | 80 | @Override 81 | public void addViewControllers(ViewControllerRegistry registry) { 82 | registry.addViewController("/about"); // the about page did not required any controller 83 | } 84 | 85 | @Override 86 | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 87 | // Serving static files using the Servlet container's default Servlet. 88 | configurer.enable(); 89 | } 90 | 91 | @Override 92 | public void addFormatters(FormatterRegistry formatterRegistry) { 93 | // add your custom formatters 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/com/javaetmoi/sample/config/datasource.properties: -------------------------------------------------------------------------------- 1 | jdbc.jndiDataSource=java:comp/env/jdbc/MyDatabase 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/com/javaetmoi/sample/config/infrastructure.properties: -------------------------------------------------------------------------------- 1 | jpa.database=H2 2 | jpa.showSql=false 3 | jpa.generateDdl=false 4 | 5 | hibernate.generate_statistics=true 6 | hibernate.dialect=org.hibernate.dialect.H2Dialect -------------------------------------------------------------------------------- /src/main/resources/jndi.properties: -------------------------------------------------------------------------------- 1 | java.naming.factory.url.pkgs=org.mortbay.naming 2 | java.naming.factory.initial=org.mortbay.naming.InitialContextFactory -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jetty-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | java:comp/env/jdbc/MyDatabase 9 | 10 | 11 | jdbc:h2:tcp://localhost/test;USER=sa 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Spring JavaConfig Sample 7 | 8 | 9 | contextClass 10 | org.springframework.web.context.support.AnnotationConfigWebApplicationContext 11 | 12 | 13 | spring.profiles.active 14 | javaee 15 | 16 | 17 | contextConfigLocation 18 | com.javaetmoi.sample.config.MainConfig 19 | 20 | 21 | 22 | org.springframework.web.context.ContextLoaderListener 23 | 24 | 25 | 26 | 27 | springSecurityFilterChain 28 | org.springframework.web.filter.DelegatingFilterProxy 29 | 30 | 31 | springSecurityFilterChain 32 | /* 33 | ERROR 34 | REQUEST 35 | 36 | 37 | 38 | 39 | mvc 40 | org.springframework.web.servlet.DispatcherServlet 41 | 42 | contextClass 43 | org.springframework.web.context.support.AnnotationConfigWebApplicationContext 44 | 45 | 46 | contextConfigLocation 47 | com.javaetmoi.sample.config.WebMvcConfig 48 | 49 | 1 50 | 51 | 52 | mvc 53 | / 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/test/java/com/javaetmoi/sample/config/SpringConfigTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package com.javaetmoi.sample.config; 15 | 16 | import org.junit.jupiter.api.Test; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.test.context.ActiveProfiles; 19 | import org.springframework.test.context.ContextConfiguration; 20 | import org.springframework.test.context.ContextHierarchy; 21 | import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; 22 | import org.springframework.test.context.web.WebAppConfiguration; 23 | import org.springframework.web.context.WebApplicationContext; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertNotNull; 26 | 27 | 28 | @SpringJUnitConfig 29 | @WebAppConfiguration 30 | @ContextHierarchy({ 31 | @ContextConfiguration(classes = MainConfig.class), 32 | @ContextConfiguration(classes = WebMvcConfig.class) }) 33 | @ActiveProfiles("test") 34 | class SpringConfigTest { 35 | 36 | @Autowired 37 | private WebApplicationContext wac; 38 | 39 | @Test 40 | void springConfiguration() { 41 | assertNotNull(wac); 42 | } 43 | } --------------------------------------------------------------------------------