I have a properties class
#ConfigurationProperties(prefix = ShiroProperties.SHIRO_PREFIX)
public class ShiroProperties {
public static final String SHIRO_PREFIX = "shiro";
private String urlLogin;
private String urlSuccessed;
and a Configuration class
#Configuration
#EnableConfigurationProperties({ ShiroProperties.class })
public class ShiroConfig implements ApplicationContextAware {
ApplicationContext applicationContext;
#Autowired
private ShiroProperties shiroProperties ;
shiroProperties is null, but i can find it value in ShiroConfig used
applicationContext.getBean(ShiroProperties.class)
my Application class:
#SpringBootApplication
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
So weird, i can run success with similar code in other project, but this.
I met this same issue as #Dean said,I had done is put the LifecycleBeanPostProcessor bean is another configure class ,and configure other Shiro in another configuration class ,see below example:
#Configuration
public class ShiroLifecycleBeanPostProcessorConfig {
/**
*
*
* #return
*/
#Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
}
The main Shiro Configuration class:
#Configuration
#AutoConfigureAfter(value = ShiroLifecycleBeanPostProcessorConfig.class)
public class ShiroConfiguration {
public static final String cacheFile = "encache.xml";
private static final String active_cache_name = "activeSessionCache";
#Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
*
*
* #throws UnknownHostException
*/
#Bean(name = "shiroFilter")
#ConditionalOnMissingBean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager)
throws UnknownHostException {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl(ShiroSecurityUrls.LOGIN_PAGE);
// shiroFilterFactoryBean.setSuccessUrl(ShiroSecurityUrls.LOGIN_SUCCESS_URL);
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl(ShiroSecurityUrls.LOGIN_PAGE);
filters.put(DefaultFilter.logout.name(), logoutFilter);
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
filterChainDefinitionManager.put("/static/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put("/node_modules/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put("/pages/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.LOGIN_PAGE, DefaultFilter.anon.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.LOGOUT_URL, DefaultFilter.logout.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.REGISTER_PROCESS_URL, DefaultFilter.anon.name());
filterChainDefinitionManager.put("/**", DefaultFilter.user.name());
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
return shiroFilterFactoryBean;
}
/**
*
*
* #throws UnknownHostException
*/
#Bean(name = "securityManager")
#DependsOn(value = { "ehCacheManager", "rememberMeManager", "sessionManager", "credentialsMatcher" })
public DefaultWebSecurityManager securityManager(EhCacheManager ehCacheManager, RememberMeManager rememberMeManager,
SessionManager sessionManager, CredentialsMatcher credentialsMatcher) throws UnknownHostException {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 1. Cache Support
securityManager.setCacheManager(ehCacheManager);
// 2. Session Support,inject the cacheManager from securitymanager
securityManager.setSessionManager(sessionManager);
// 3. Rememberme Support
securityManager.setRememberMeManager(rememberMeManager);
// 4. JDBC,LDAP Realm implements
Collection<Realm> authorizingRealms = Lists.newArrayList(shiroDatabaseRealm(credentialsMatcher),
shiroActiveDirectoryRealm(credentialsMatcher));
securityManager.setRealms(authorizingRealms); // inject the cacheManager
// from securitymanager
if (securityManager.getAuthenticator() instanceof ModularRealmAuthenticator) {
ModularRealmAuthenticator modularRealmAuthenticator = (ModularRealmAuthenticator) securityManager
.getAuthenticator();
modularRealmAuthenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
}
return securityManager;
}
}
Hope this code helps you ,thanks.
This being another configuration class for your application should be decorated with #Configuration annotation to enable a bean creation and injection into the context for wiring from another classes.
In common, AutowiredAnnotationBeanPostProcessor set such property annotationed by #Autowired in the phase when Spring load FactoryBean classes. If the following factory beans:
ApplicationContextAwareProcessor
ApplicationListenerDetector
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
PostProcessorRegistrationDelegate$BeanPostProcessorChecker
CommonAnnotationBeanPostProcessor
refer your config bean, your bean will not be autowired properties after creation due to AutowiredAnnotationBeanPostProcessor is not loaded.
For example, properties is null and throw NullPointerException
#Component
public class BeanFactoryTest {
#Autowired
private IdGenProperties properties;
#Bean
public SnowflakeServer snowflakeServer() {
System.out.println(properties.getBaseUrl());
return null;
}
#Bean(name = "conversionService")
public ConversionServiceFactoryBean getConversionService() {
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
Set<Converter> converters = new HashSet<>();
converters.add(new StringToDateConverter());
bean.setConverters(converters);
return bean;
}
public static class StringToDateConverter implements Converter<String, Date>
{
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
}
Try with adding #Component in your ShiroProperties.class
#Component
#ConfigurationProperties(prefix = ShiroProperties.SHIRO_PREFIX)
public class ShiroProperties {
public static final String SHIRO_PREFIX = "shiro";
private String urlLogin;
private String urlSuccessed;
}
Related
I am trying to run test for add data to database using Spring Hibernate. I assigned #Bean for function getSessionFactory in HibernateConfig.java, but when I call again in DAOImp file, I get error Could not autowire. No beans of 'SessionFactory' type found.
HibernateConfig.java
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages = {"com.huyvt.onlineshopping.dto"})
public class HibernateConfig {
private final static String DATABASE_URL = "jdbc:mysql://localhost:3308/onlineshopping?serverTimezone=UTC";
private final static String DATABASE_DRIVER = "com.mysql.jdbc.Driver";
private final static String DATABASE_DIALECT = "org.hibernate.dialect.H2Dialect";
private final static String DATABASE_USER = "root";
private final static String DATABASE_PASSWORD = "";
#Bean
public DataSource getDataSource(){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(DATABASE_DRIVER);
dataSource.setUrl(DATABASE_URL);
dataSource.setUsername(DATABASE_USER);
dataSource.setPassword(DATABASE_PASSWORD);
return dataSource;
}
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
LocalSessionFactoryBuilder sessionFactoryBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionFactoryBuilder.addProperties(getHibernateProperties());
return sessionFactoryBuilder.buildSessionFactory();
}
private Properties getHibernateProperties(){
Properties properties = new Properties();
properties.put("hibernate.dialect", DATABASE_DIALECT);
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
return properties;
}
#Bean
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory){
return new HibernateTransactionManager(sessionFactory);
}
}
CategoryDAOImp.java
#Repository("categoryDAO")
public class CategoryDAOImp implements CategoryDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public boolean add(Category category) {
try {
//add category to db
System.out.println(category.toString());
sessionFactory.getCurrentSession().persist(category);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
How can I fix it?
In which package is your HibernateConfig class found ?
This
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
is not being executed.
To confirm, you could do a 'System.out.println("XXX")' like so:
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
System.out.println("sessionFactory bean is getting created")
...
}
and check if you can see it in your console when you launch your application.
To ensure that it is being picked up, the easiest way is to ensure that you have a #ComponentScan in your root class found here com.huyvt.onlineshopping.
#ComponentScan without arguments tells Spring to scan the current
package and all of its sub-packages.
If you are using Spring Boot, this is automatically added for you when you are using #SpringBootApplication.
Also, in your main method, you can check your created beans like so:
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext =
new AnnotationConfigApplicationContext(SpringComponentScanApp.class);
for (String beanName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanName);
}
}
I am having trouble caching internal methods within my DAO layer while in Proxy mode.
I am aware that while in Proxy mode, only external method calls coming in through the proxy are intercepted. However,I want to avoid having to switch to AspectJ mode and was wondering if any other work arounds existed.
I am displaying my code below and am wondering what changes, if any, I can add to make this process work.
--Note I am using swagger to document my code
--Also note my code has been watered down....for obvious reasons
//Controller
#RestController
#Api(produces = "application/json", protocols = "https", tags = "Securities", description = "Securities information")
public class SecuritiesInfoController extends Controller {
private SecuritiesInfoManager _securitiesInfoManager = new SecuritiesInfoManager();
#RequestMapping(value = "/security", method = RequestMethod.GET)
public List<SecuritiesInfo> getAll(){
return _securitiesInfoManager.getAll();
}
}
//Service
public class SecuritiesInfoManager extends Manager {
private SecuritiesInfoDAO _securitiesDAO = new SecuritiesInfoDAO();
public List<SecuritiesInfo> getAll() {
return _securitiesDAO.getAll();
}
}
//DAO
public class SecuritiesInfoDAO extends DAO {
private static String securitiesTable = "Securities";
#SecuritiesInfoDAOInterface
public List<SecuritiesInfo> getAll() {
//Magic
}
}
//Interface
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD})
#Cacheable(cacheNames = "SecuritiesInfo",cacheManager="cacheManager",
keyGenerator="keyGenerator" )
public #interface SecuritiesInfoDAOInterface {
}
//CacheConfig
#Configuration
//#EnableCaching(mode = AdviceMode.PROXY)
#EnableCaching(proxyTargetClass = true)
//#EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
#Bean
public SecuritiesInfoDAO myService() {
// configure and return a class having #Cacheable methods
return new SecuritiesInfoDAO();
}
#Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
// Defaults
redisConnectionFactory.setHostName("Nope");
redisConnectionFactory.setPort(LoL);
System.out.println("IN CONNTECTION");
redisConnectionFactory.setPassword("Please help me :)");
return redisConnectionFactory;
}
#Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
System.out.println("cf: "+cf.toString());
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
/*
#Primary
#Bean
public RedisTemplate<String,ExpiringSession> redisTemplate2(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
template.setHashValueSerializer(new LdapFailAwareRedisObjectSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
*/
#Bean
public CacheManager cacheManager(RedisTemplate<String, String> redisTemplate) {
System.out.println("IN CACHE MANAGER");
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
// cacheManager.setDefaultExpiration(300);
return cacheManager;
}
#Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
#Override
public Object generate(Object o, Method method, Object... objects) {
// This will generate a unique key of the class name, the method name,
// and all method parameters appended.
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
System.out.println(sb.toString());
return sb.toString();
}
};
}
So I figured out the answer. It turns out I wasn't implementing/instantiating the interface correctly.
First I have to #Autowire my manager class in my controller. Then #autowire my interface class in my manager.
For a more detailed solution, I am placing my revised code below.
//Controller
#RestController
#Api(produces = "application/json", protocols = "https", tags = "Securities", description = "Securities information")
public class SecuritiesInfoController extends Controller {
#Autowired
private SecuritiesInfoManager _securitiesInfoManager = new SecuritiesInfoManager();
#RequestMapping(value = "/security", method = RequestMethod.GET)
public List<SecuritiesInfo> getAll(){
return _securitiesInfoManager.getAll();
}
}
//Service
public class SecuritiesInfoManager extends Manager {
#Autowired
public void setSecuritiesInfoDAOInterface(SecuritiesInfoDAOInterface _securitiesInfoDAOInterface) {
this._securitiesInfoDAOInterface = _securitiesInfoDAOInterface;
}
public List<SecuritiesInfo> getAll() {
return _securitiesInfoDAOInterface.getAll();
}
}
//DAO
public class SecuritiesInfoDAO extends DAO implements SecuritiesInfoDAOInterface {
private static String securitiesTable = "Securities";
#Override
public List<SecuritiesInfo> getAll() {
//Magic
}
}
//Interface
public interface SecuritiesInfoDAOInterface {
#Cacheable(cacheNames = "SecuritiesInfo",cacheManager="cacheManager", keyGenerator="keyGenerator" )
List<SecuritiesInfo> getAll();
}
}
//CacheConfig
#Configuration
#EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
#Bean
public SecuritiesInfoManager myService() {
// configure and return a class having #Cacheable methods
return new SecuritiesInfoManager();
}
//rest same as before
}
//WebConfig
#Configuration
#ComponentScan(basePackages = {"package name"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
AntPathMatcher matcher = new AntPathMatcher();
matcher.setCaseSensitive(false);
configurer.setPathMatcher(matcher);
}
}
I'm facing a situation where the Beans I've created are not accessible which makes me wonder where and when they are!?
I've made two Beans, one scoped singleton and other scoped request. I've made sure they are correctly implemented by autowiring them in a RestController class. And they are populated, no doubt there.
Now I have written an authorization checker class extending PreInvocationAuthorizationAdvice. Being an authorization class, I need to have access to current user's information. So I autowired current user's Bean to this class, this is the request scoped Bean. Also I need a customized ACL engine, which is autowired in a singleton manner. But when I reach the point when I need to use these two properties, they are both null!
So what are limitations on where and when I can expect a Bean to be accessible?
BTW, my #Configuration class is also annotated by #ComponentScan({"my.base.package"}) which is a parent package of my designated class including the #Autowired property.
[UPDATE]
I think I found what the problem is, but yet I'm struggling with the solution.
The class with #Autowired properties, is being instantiated as Bean itself. I think this late Bean is getting instantiated before the other Beans which it is depending on and as the result they are not yet available. Is there anyway I can specify the ordering of the Beans being instantiated?
[P.S.]
Anyone who flagged this question as "off-topic because: This question does not appear to be about programming" is so funny :)
[UPDATE]
Just an example when #Autowired property is null.
These are my configuration classes:
#Configuration
#PropertySource("/config.properties")
#ComponentScan({"my.package"})
public class AppConfig implements ApplicationContextAware
{
private ApplicationContext appContext;
#Autowired
private Environment env;
#Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
this.appContext = applicationContext;
}
#Bean
public RedissonClient getRedisson()
{
//Code ommited: returning a redisson connection.
}
}
#Configuration
#ComponentScan({"my.pacakge"})
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends GlobalMethodSecurityConfiguration
{
#Bean
public AclEngine getAclEngine()
{
return new AclEngine();
}
#Autowired
private RedissonClient redisson;
#Bean
#Scope(value = "request")
public User getCurrentUser()
{
//Code ommited: retrieving the user from Redisson and returning it.
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
{
auth.authenticationProvider(authenticator());
}
#Bean
public AuthenticationProvider authenticator()
{
return new AclAuthenticationProvider();
}
#Bean
HttpSessionSecurityContextRepository getHttpSessionSecurityContextRepository()
{
HttpSessionSecurityContextRepository x = new HttpSessionSecurityContextRepository();
x.setAllowSessionCreation(false);
return x;
}
#Bean
SecurityContextPersistenceFilter getSecurityContextPersistenceFilter()
{
return new SecurityContextPersistenceFilter(getHttpSessionSecurityContextRepository());
}
#Override
protected AccessDecisionManager accessDecisionManager()
{
try {
AffirmativeBased ab = (AffirmativeBased) super.accessDecisionManager();
List<AccessDecisionVoter<? extends Object>> advs = ab.getDecisionVoters();
ResourceBasedPreInvocationAdvice expressionAdvice = new ResourceBasedPreInvocationAdvice();
List<AccessDecisionVoter<? extends Object>> toBeRemoved = new ArrayList<>();
for (AccessDecisionVoter<? extends Object> adv : advs) {
if (adv instanceof PreInvocationAuthorizationAdviceVoter) {
toBeRemoved.add(adv);
}
}
for (AccessDecisionVoter<? extends Object> adv : toBeRemoved) {
advs.remove(adv);
}
advs.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
return ab;
}
catch (ClassCastException ex) {
ArrayList decisionVoters = new ArrayList();
ResourceBasedPreInvocationAdvice expressionAdvice = new ResourceBasedPreInvocationAdvice();
decisionVoters.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
return new AffirmativeBased(decisionVoters);
}
}
public class AclAuthenticationProvider implements AuthenticationProvider
{
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
return null;
}
#Override
public boolean supports(Class<?> authentication)
{
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer
{
public SessionInitializer()
{
super(SecurityConfig.class);
}
}
}
And finally where I face the problem:
public class ResourceBasedPreInvocationAdvice implements PreInvocationAuthorizationAdvice
{
#Autowired
private User currentUser;
#Autowired
private AclEngine aclEngine;
#Override
public boolean before(Authentication authentication, MethodInvocation methodInvocation, PreInvocationAttribute preInvocationAttribute)
{
//Where I want to access currentUser and aclEngine but they are null.
//I can trace the code to this point without any Exception thrown!
}
}
#Override
protected AccessDecisionManager accessDecisionManager()
{
try {
AffirmativeBased ab = (AffirmativeBased) super.accessDecisionManager();
List<AccessDecisionVoter<? extends Object>> advs = ab.getDecisionVoters();
ResourceBasedPreInvocationAdvice expressionAdvice = new ResourceBasedPreInvocationAdvice();
List<AccessDecisionVoter<? extends Object>> toBeRemoved = new ArrayList<>();
for (AccessDecisionVoter<? extends Object> adv : advs) {
if (adv instanceof PreInvocationAuthorizationAdviceVoter) {
toBeRemoved.add(adv);
}
}
for (AccessDecisionVoter<? extends Object> adv : toBeRemoved) {
advs.remove(adv);
}
advs.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
return ab;
}
catch (ClassCastException ex) {
ArrayList decisionVoters = new ArrayList();
ResourceBasedPreInvocationAdvice expressionAdvice = new ResourceBasedPreInvocationAdvice();
decisionVoters.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
return new AffirmativeBased(decisionVoters);
}
}
Spring will only inject references into class instances (aka beans) that it manages. When you are creating beans inside methods and directly inject them into other beans, those newly created beans are Spring Managed beans and as such aren't eligible for any auto wiring or post processing by spring whatsoever.
Instead of
ResourceBasedPreInvocationAdvice expressionAdvice = new ResourceBasedPreInvocationAdvice();
You should move that code to a #Bean method so that is becomes a Spring managed bean and will be injected with the dependencies.
#Bean
public ResourceBasedPreInvocationAdvice expressionAdvice() {
return new ResourceBasedPreInvocationAdvice();
}
And just reference this method instead of creating a new instance.
ResourceBasedPreInvocationAdvice expressionAdvice = expressionAdvice();
I have an application which needs a service to be Spring wired in a JsonDeserializer. The problem is that when I start up the application normally it is wired, but when I start it up in a test, it is null.
The relevant code is:
JSON Serializer/Deserializer:
#Component
public class CountryJsonSupport {
#Component
public static class Deserializer extends JsonDeserializer<Country> {
#Autowired
private CountryService service;
#Override
public Country deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
return service.getById(jsonParser.getValueAsLong());
}
}
}
Domain Object:
public class BookingLine extends AbstractEntity implements TelEntity {
.....other fields
//Hibernate annotations here....
#JsonDeserialize(using = CountryJsonSupport.Deserializer.class)
private Country targetingCountry;
..... other fields
}
Test Class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(Application.class)
#WebIntegrationTest({"server.port=0"})
#ActiveProfiles("test")
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class BookingAndLinesControllerFunctionalTest {
#Test
public void testGetBooking() {
Booking booking = bookingRepositoryHelper.createBooking();
bookingRepository.save(booking);
String uri = String.format("http://localhost:%s/api/v1/booking-and-lines/" + booking.getBookingCode(), port);
Booking booking1 = restTemplate.getForObject(uri, Booking.class); // line which falls over because countryService is null
}
}
Any ideas?
Managed to discover the answer to this one after fiddling around long enough. Just needed some config like this:
#Configuration
#Profile("test")
public class TestConfig {
#Bean
public HandlerInstantiator handlerInstantiator() {
return new SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());
}
#Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(HandlerInstantiator handlerInstantiator) {
Jackson2ObjectMapperBuilder result = new Jackson2ObjectMapperBuilder();
result.handlerInstantiator(handlerInstantiator);
return result;
}
#Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(Jackson2ObjectMapperBuilder objectMapperBuilder) {
return new MappingJackson2HttpMessageConverter(objectMapperBuilder.build());
}
#Bean
public RestTemplate restTemplate(MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter) {
List<HttpMessageConverter<?>> messageConverterList = new ArrayList<>();
messageConverterList.add(mappingJackson2HttpMessageConverter);
return new RestTemplate(messageConverterList);
}
}
Here I have my main class with #Service called RegionsServiceImpl. I'm initializing it with ApplicationContext.getBean, but I want to use #Autowired. And when I do, #Autowired doesn't initialize it.
Main class:
package com.rebel.shop;
public class JpaRepoTest {
//ApplicationContext ctx;
#Autowired
RegionsServiceImpl regionsServiceImpl;
public JpaRepoTest() {
// ctx = new AnnotationConfigApplicationContext(DataConfig.class);
// regionsServiceImpl = ctx.getBean("regionsServiceImpl", RegionsServiceImpl.class);
}
public static void main(String[] args) {
JpaRepoTest jpaRepoTest = new JpaRepoTest();
jpaRepoTest.testService();
}
private void testService() {
System.out.println(regionsServiceImpl.findById(3l).getName());
}
}
My Service class:
package com.rebel.shop.persistence.jpa.service;
#Service
public class RegionsServiceImpl implements RegionsService {
#Resource
private RegionsRepository regionsRepository;
#Override
public Regions findById(long id) {
return regionsRepository.findOne(id);
}
}
It's interface:
package com.rebel.shop.persistence.jpa.service;
public interface RegionsService {
public Regions findById(long id);
}
Repo:
package com.rebel.shop.persistence.jpa.repository;
public interface RegionsRepository extends JpaRepository<Regions, Long> {
}
And Java Config For Spring:
package com.rebel.shop.persistence.jpa.config;
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:app.properties")
#EnableJpaRepositories("com.rebel.shop.persistence.jpa.repository")
#ComponentScan("com.rebel.shop")
public class DataConfig {
private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_PASSWORD = "db.password";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PROP_ENTITYMANAGER_PACKAGES_TO_SCAN = "db.entitymanager.packages.to.scan";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
#Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(false);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.rebel.shop.persistence.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
// #Bean
// RegionsServiceImpl regionsServiceImpl() {
// return new RegionsServiceImpl();
// }
}
Thanks in advance!
UPD1:
Exception:
Exception in thread "main" java.lang.NullPointerException
at com.rebel.shop.JpaRepoTest.testService(JpaRepoTest.java:33)
at com.rebel.shop.JpaRepoTest.main(JpaRepoTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
You are not using the spring container, rather you are instantiating the object using new, hence no spring bean will be autowired, Modify your bean as below
package com.rebel.shop;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(DataConfig.class)
public class JpaRepoTest {
//ApplicationContext ctx;
#Autowired
RegionsServiceImpl regionsServiceImpl;
public JpaRepoTest() {
// ctx = new AnnotationConfigApplicationContext(DataConfig.class);
// regionsServiceImpl = ctx.getBean("regionsServiceImpl", RegionsServiceImpl.class);
}
#Test
public void mainMethod() {
testService();
}
private void testService() {
System.out.println(regionsServiceImpl.findById(3l).getName());
}
}