Reputation: 13394
I have one AppConfig.java and one SecurityConfig.java file in my project, I was following some blog on web and saw below configuration setting..
package mybasepackage.login.springsecurity.config;
@Configuration
@EnableWebMvc
@ComponentScan({"mybasepackage.login.springsecurity.*"})
public class AppConfig {
@Bean(name = "dataSource")
public DataSource getDataSource() {
//code to construct datasource
}
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return new CustomPasswordEncoder();
}
}
package mybasepackage.login.springsecurity.config;
@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder passwordEncoder;
}
However when I try above code I get BeanCreationException because datasource can't be created.
When I use below code, it works as expected,
package mybasepackage.login.springsecurity.config;
@Configuration
public class AppConfig {
@Bean(name = "dataSource")
public DataSource dataSource() {
//code to create dataSource
}
@Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return new CustomPasswordEncoder();
}
}
package mybasepackage.login.springsecurity.config;
@Configuration
@EnableWebSecurity
@Import({ AppConfig.class })
@ComponentScan({ "mybasepackage.login.springsecurity.*" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder passwordEncoder;
}
However I can't understand why the first (correct and recommended) approach is not working and why the second approach is working ?
Also, in either case my controller which is in mybasepackage.login.springsecurity.controller package is never never recognized by the system, is that also related to this strange behavior ?
Upvotes: 2
Views: 88
Reputation: 48213
@ComponentScan({"mybasepackage.login.springsecurity.*"})
There is no need for .* for base packages, it's recursive by default.
I guess dispatcher servlet
config (AppConfig
in your example) is child context and another one is parent context and you can't reference to child beans from parent.
It's better to sperate your spring configurations based on say architectural aspects and only define related beans to that aspect in each config. For example, you could have a WebConfig
java config which is annotated by EnableWebMvc
and defines web related stuff, a DataConfig
which defines your data related beans such as DataSource
, TransactionManager
, ... and a SecurityConfig
which is annotated by EnableWebSecurity
and defines security beans such as PasswordEncoder
,... .
Upvotes: 1
Reputation:
here i have sample application configuration.
spring-servlet xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan base-package="com.WordOfTheDay" />
<mvc:interceptors>
<bean id="webContentInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0" />
<property name="useExpiresHeader" value="false" />
<property name="useCacheControlHeader" value="true" />
<property name="useCacheControlNoStore" value="true" />
</bean>
</mvc:interceptors>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/Messages" />
<property name="cacheSeconds" value="3000" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.CharSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.WordOfTheDay"></property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/demo"
p:username="root" p:password="123" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
</beans>
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="true">
<security:intercept-url pattern="/login.do"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout.do"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/fail2login.do"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/json/*.do"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/*" access="ROLE_ADMIN" />
<security:form-login login-page="/login.do"
default-target-url="/home.do" authentication-failure-url="/fail2login.do" />
<security:session-management>
<security:concurrency-control
max-sessions="1" />
</security:session-management>
<security:logout logout-success-url="/logout.do"
delete-cookies="JSESSIONID" invalidate-session="true" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select userName, password, status from User where userName=?"
authorities-by-username-query="select us.userName, ur.userRoleName from User us, UserRole ur
where ur.userName =? " />
</security:authentication-provider>
</security:authentication-manager>
</beans>
xml base configuration maybe very easy.
Upvotes: 0