http://blog.csdn.net/chenyufeng1991/article/details/78242369
http://stackoverflow.com/questions/2520722/is-it-possible-from-spring-to-inject-the-result-of-calling-a-method-on-a-ref-bea
http://stackoverflow.com/questions/24903658/spring-threadpooltaskexecutor-vs-java-executorservice-cachedthreadpool
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/expression/MethodBasedEvaluationContext.html
https://www.dotkam.com/2010/09/10/spring-expression-language-calling-a-method-with-parameters/
EvaluationContext context = new StandardEvaluationContext( lottery );
context.setVariable( "amount", amount );
context.setVariable( "date", calendar.getTime() );
ExpressionParser parser = new SpelExpressionParser();
// using '#' to identify a variable ( NOTE: #this, #root are reserved variables )
Expression exp = parser.parseExpression( "congratulateWinner( 'Anatoly', #amount, #date )" );
String congratulations = ( String ) exp.getValue( context );
https://www.mkyong.com/spring3/test-spring-el-with-expressionparser/
http://www.codejava.net/frameworks/hibernate/hibernate-basics-3-ways-to-delete-an-entity-from-the-datastore
This way is simple and straightforward, because we don’t have to load a persistent instance from the datastore before deleting it. However, its drawback is that it doesn’t remove the associated instances, even an appropriate cascade type is specified in the class mappings/annotations. Consider the following statements:
If the category (ID=17) is associated with some products (in the datastore), the code will throws a ConstraintViolationException at runtime because Hibernate attempts to remove only the category while it is still referenced by some products. We would see an error message like this:
RestTemplate
http://stackoverflow.com/questions/20705377/resttemplate-urivariables-not-expanded
RestTemplate is thread-safe once constructed, and that you can use callbacks to customize its operations.
http://www.baeldung.com/rest-template
http://learningviacode.blogspot.com/2013/06/using-springs-resttemplate-class.html
http://techblog.outbrain.com/2014/05/so-long-spring-xmls/
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper
http://stackoverflow.com/questions/34728814/spring-boot-with-two-mvc-configurations
How to customise the Jackson JSON mapper in Spring Web MVC
http://magicmonster.com/kb/prg/java/spring/webmvc/jackson_custom.html
http://stackoverflow.com/questions/32356935/mappingjacksonhttpmessageconverter-not-found-with-spring4
http://stackoverflow.com/questions/7854030/configuring-objectmapper-in-spring
https://objectpartners.com/2015/12/07/avoiding-a-common-spring-annotation-configuration-mistake/
Scope
https://www.tutorialspoint.com/spring/spring_bean_scopes.htm
http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection
Hibernate
http://shengwangi.blogspot.com/2015/12/most-used-hibernate-properties-during-development.html
There is also no need for hibernate.hbm2ddl.auto. Spring boot will also auto detect if the database used is a embedded one, like HSQL, H2 or Derby, or external database. If a embedded database is used, default is create-drop. Otherwise for external database, default is none. (No tables will be auto created). You can set this behavior in spring boot's configuration file application.properties with spring.jpa.hibernate.ddl-auto= create, for example.
To inject complex properties using
ConfigurationProperties
http://www.jianshu.com/p/df57fefe0ab7
https://dzone.com/articles/spring-boot-configurationproperties-1
https://blog.synyx.de/2016/11/bean-x-of-type-y-is-not-eligible-for-getting-processed-by-all-beanpostprocessors/
http://stackoverflow.com/questions/24301074/spring-cacheable-with-ehcache-spel-find-null-for-valid-object
spring @Cacheable with Ehcache, spel find null for valid object
That’s not a work-around, that’s the solution. SpEL cannot access arguments by name if that information is not available. You need at least
My pom compiler config had debug:false, added debug:true and it works after maven build, updated post. Have jdk=7u55(IcedTea 2.4.7)64bit on linux
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
@CacheEvict on Multiple Objects Using Annotations
http://stackoverflow.com/questions/11854408/ehcache-cacheevict-on-multiple-objects-using-annotations
CacheAspectSupport.execute
SpringCacheAnnotationParser.parseCacheAnnotations
http://stackoverflow.com/questions/39432764/info-warnings-about-multiple-modules-in-spring-boot-what-do-they-mean
https://github.com/spring-projects/spring-data-examples/tree/master/multi-store
https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/main/java/example/springdata/jpa/caching/CachingUserRepository.java
https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/test/java/example/springdata/jpa/caching/CachingRepositoryTests.java
@Cacheable("byUsername") User findByUsername(String username);
@Cacheable
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
cache timeout
http://stackoverflow.com/questions/27968157/expiry-time-cacheable-spring-boot
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/htmlsingle/#cache-specific-config
How can I set the TTL/TTI/Eviction policy/XXX feature?
Directly through your cache provider. The cache abstraction is… well, an abstraction not a cache implementation. The solution you are using might support various data policies and different topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.
redis cache
https://my.oschina.net/wnjustdoit/blog/644311
扩展基于注解的spring缓存,使缓存有效期的设置支持方法级别-redis篇
<property name="defaultExpiration" value="3600"/> <!-- 多个缓存有效期,一般的单个工程可以省略此项 --> <property name="expires"> <map> <entry key="caiya_a" value="1800"/> </map> </property>
http://stackoverflow.com/questions/34893279/spring-data-redis-expire-key
http://stackoverflow.com/questions/34201135/spring-redis-read-configuration-from-application-properties-file
https://www.javacodegeeks.com/2013/02/caching-with-spring-data-redis.html
https://github.com/caseyscarborough/spring-redis-caching-example/blob/master/src/main/java/com/caseyscarborough/spring/redis/config/CacheConfig.java
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
http://docs.spring.io/spring-data/redis/docs/current/reference/html/
http://stackoverflow.com/questions/36623208/spring-redistemplate-after-8-calls-method-keys-hangs-up
http://www.jianshu.com/p/a78de210a947
https://segmentfault.com/a/1190000005885205
Cache
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
Sometimes, a method might not be suitable for caching all the time (for example, it might depend on the given arguments). The cache annotations support such functionality through the
https://www.foreach.be/blog/spring-cache-annotations-some-tips-tricks
Spring-data logging
https://docs.datastax.com/en/developer/java-driver/2.1/manual/logging/#logging-query-latencies
https://docs.datastax.com/en/cassandra/2.1/cassandra/configuration/configLoggingLevels_r.html
http://docs.spring.io/spring-data/cassandra/docs/2.0.x/reference/html/
https://lostechies.com/ryansvihla/2016/04/07/logging-the-generated-cql-from-the-spark-cassandra-connector/
<logger name=”com.datastax.driver.core.RequestHandler” level=”TRACE”/>
Spring Data Converter
https://gist.github.com/harlanji/1179718
Need to call
there is one alternate way to inject dependency that is not documented well, it is to just take the dependency as a `@Bean` method parameter this way:
encrypt property
https://github.com/ulisesbocchio/jasypt-spring-boot
http://www.seropian.eu/2015/05/spring-boot-jasypt-easy-encrypted-properties.html
https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
org.springframework.context.annotation.ConfigurationClassParser
org.springframework.context.annotation.ConfigurationClassParser.processPropertySource(AnnotationAttributes)
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
https://www.mkyong.com/spring/spring-inject-a-value-into-static-variables/
http://stackoverflow.com/questions/38731419/how-to-add-servlet-filter-using-spring-factories
Spring's central class for synchronous client-side HTTP access. It simplifies communication with HTTP servers, and enforces RESTful principles. It handles HTTP connections, leaving application code to provide URLs (with possible template variables) and extract results.
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-restclient.html
hibernate-validator
http://stackoverflow.com/questions/21444878/spring-data-solr-how-to-get-suggestions
https://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
https://github.com/spring-projects/spring-boot/search?l=Maven+POM&q=hibernate-validator&utf8=%E2%9C%93
https://github.com/christophstrobl/spring-data-solr-showcase
FacetPage<Product> result = productService.autocompleteNameFragment(query, pageable);
http://projects.spring.io/spring-data-solr/
https://github.com/spring-projects/spring-data-solr
https://github.com/spring-projects/spring-data-solr-examples
http://docs.spring.io/spring-data/solr/docs/current/reference/html/
Use
need @Id
https://discuss.pivotal.io/hc/en-us/articles/202653068-Registering-unregistering-scheduling-and-unscheduling-Task-Scheduler-at-runtime-in-Spring-Framework-3-0-3-1-2010476-
How do I manually autowire a bean with Spring?
http://stackoverflow.com/questions/11965600/how-do-i-manually-autowire-a-bean-with-spring
private AutowireCapableBeanFactory beanFactory;
https://spring.io/blog/2011/08/09/what-s-a-factorybean
A
http://stackoverflow.com/questions/25012051/difference-between-defining-queries-in-the-repository-interface-or-entity-class
在Spring3之前进行类型转换都是使用PropertyEditor,使用PropertyEditor的setAsText()方法可以实现String转向特定的类型,但是它的最大的一个缺陷就是只支持String转为其他类型。
Spring中的三种类型转换接口分别为:
- Converter接口:使用最简单,但是不太灵活;
- ConverterFactory接口:使用较复杂,稍微灵活一点;
- GenericConverter接口:使用最复杂,也最灵活;
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"
<property name="converters"
<set>
<bean class="com.chenyufeng.springmvc.common.converter.StringToGenderEnumConverter"/>
</set>
</property>
</bean>
http://stackoverflow.com/questions/2520722/is-it-possible-from-spring-to-inject-the-result-of-calling-a-method-on-a-ref-bea
<bean id="registryService" class="foo.MyRegistry">
...properties set etc...
</bean>
<bean id="MyClient" class="foo.MyClient">
<property name="endPoint" value="#{registryService.getEndPoint('bar')}"/>
</bean>
http://stackoverflow.com/questions/24903658/spring-threadpooltaskexecutor-vs-java-executorservice-cachedthreadpool
One of the added Advantage of using ThreadPoolTaskExecutor of spring is that it is well suited for management and monitoring (e.g. through JMX), providing several useful attributes: "corePoolSize", "maxPoolSize", "keepAliveSeconds" (all supporting updates at runtime); "poolSize", "activeCount".
apart from that it is obviously simple to use if you already have spring injections implemented in your application. by using it you can directly inject thread pool by setter injection
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/expression/MethodBasedEvaluationContext.html
https://www.dotkam.com/2010/09/10/spring-expression-language-calling-a-method-with-parameters/
EvaluationContext context = new StandardEvaluationContext( lottery );
context.setVariable( "amount", amount );
context.setVariable( "date", calendar.getTime() );
ExpressionParser parser = new SpelExpressionParser();
// using '#' to identify a variable ( NOTE: #this, #root are reserved variables )
Expression exp = parser.parseExpression( "congratulateWinner( 'Anatoly', #amount, #date )" );
String congratulations = ( String ) exp.getValue( context );
https://www.mkyong.com/spring3/test-spring-el-with-expressionparser/
Item item = new Item("mkyong", 100);
//test EL with item object
StandardEvaluationContext itemContext = new StandardEvaluationContext(item);
//display the value of item.name property
Expression exp4 = parser.parseExpression("name");
String msg4 = exp4.getValue(itemContext, String.class);
System.out.println(msg4);
//test if item.name == 'mkyong'
Expression exp5 = parser.parseExpression("name == 'mkyong'");
boolean msg5 = exp5.getValue(itemContext, Boolean.class);
System.out.println(msg5);
http://stackoverflow.com/questions/18021071/spring-aop-interceptor-not-working
Spring AOP only works for spring beans. You should define the intercepted object as a bean in the spring config file, get it from the context and invoke method on it.
http://www.devjavasource.com/cassandra/spring-data-cassandra-delete-operation/CassandraOperations cassandraOps = new CassandraTemplate(session); |
Using delete() method of CassandraTemplate class, we can delete single
or multiple records from Cassandra Database.
or multiple records from Cassandra Database.
// To delete a single User information from Database
cassandraOps.delete(
new
Users(
11104
,
"UK_updated"
,
"Alex"
));
//To delete a single User information from Database, by Id
cassandraOps.deleteById(Users.
class
,
11104
);
// To delete multiple User information at a time.
// Bulk delete operation
final
Users user1 =
new
Users(
11105
,
"Australia"
,
"Mike_updated"
);
final
Users user2 =
new
Users(
11106
,
"India"
,
"Ram_updated"
);
final
List<Users> userList =
new
ArrayList<>();
userList.add(user1);
userList.add(user2);
cassandraOps.delete(userList);
http://www.codejava.net/frameworks/hibernate/hibernate-basics-3-ways-to-delete-an-entity-from-the-datastore
1. Deleting a transient instance
The Session.delete(Object) method allows us to remove a transient instance of the entity with an identifier associated with existing persistent state. A transient instance is the one which does not associate with the session. For example, the following statements delete a product whose identifier equals to 37:
1
2
3
| Product product = new Product(); product.setId( 37 ); session.delete(product); |
1
2
3
| Category cat = new Category(); cat.setId( 17 ); session.delete(cat); |
1
2
| ERROR: Cannot delete or update a parent row: a foreign key constraint fails (`stockdb`.`product`, CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`)) |
Deleting a persistent instance
In this way, we load a persistent instance using the Session.load(Class, ID) method before deleting itSerializable id =
new
Long(
17
);
Object persistentInstance = session.load(Category.
class
, id);
if
(persistentInstance !=
null
) {
session.delete(persistentInstance);
}
http://stackoverflow.com/questions/20705377/resttemplate-urivariables-not-expanded
There is no append some query string logic in
RestTemplate
it basically replace variable like {foo}
by their value:http://www.sample.com?foo={foo}
https://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplateRestTemplate is thread-safe once constructed, and that you can use callbacks to customize its operations.
http://www.baeldung.com/rest-template
http://learningviacode.blogspot.com/2013/06/using-springs-resttemplate-class.html
http://techblog.outbrain.com/2014/05/so-long-spring-xmls/
@EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { System.out.println( "Spring Security init..." ); auth .inMemoryAuthentication() .withUser( "user" ).password( "password" ).roles( "USER" ); } } |
1
2
3
4
5
6
7
8
9
10
11
| import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc @ComponentScan (basePackages = "net.lkrnac.blog.dontscanconfigurations" ) public class WebConfig extends WebMvcConfigurerAdapter { } |
Pay attention to the component scanning in
WebConfig
. It is scanning package where all three classes are located. When you run this on servlet container, text “Spring Security init…” is written to console twice. It mean mean SecurityConfig
configuration is loaded twice. It was loaded- During initialization of servlet container in method
AppInitializer.getRootConfigClasses()
- By component scan in class
WebConfig
Why? I found this explanation in Spring’s documentation:
Remember that
@Configuration
classes are meta-annotated with @Component
, so they are candidates for component-scanning!
So this is feature of Spring and therefore we want to avoid component scanning of Spring
@Configuration
used by Servlet configuration. Brett Ryan independently found this problem and showed his solution in mentioned Stack Overflow question:
1
2
3
4
5
6
7
8
| @ComponentScan (basePackages = "com.acme.app" , excludeFilters = { @Filter (type = ASSIGNABLE_TYPE, value = { WebConfig. class , SecurityConfig. class }) }) |
I don’t like this solution. Annotation is too verbose for me. Also some developer can create new
http://www.javainterviewpoint.com/spring-mvc-difference-between-contextannotation-config-vs-contextcomponent-scan/@Configuration
class and forget to include it into this filter. I would rather specify special package that would be excluded from Spring’s component scanning.<context:component-scan>
<context:annotation-config>
- The <context:annotation-config> tag activates the annotation of the beans which is already registered in the application context. It doesn’t bother how it is registered if it is by <context:component-scan> or defined in the xml itself.
- It mainly activates the 4 types of BeanPostProcessors
- CommonAnnotationBeanPostProcessor : @PostConstruct, @PreDestroy, @Resource
- AutowiredAnnotationBeanPostProcessor : @Autowired, @Value, @Inject, @Qualifier, etc
- RequiredAnnotationBeanPostProcessor : @Required annotation
- PersistenceAnnotationBeanPostProcessor :@PersistenceUnit and @PersistenceContext annotations
<context:component-scan>
- The main function of <context:component-scan> tag is to register the beans to the context and also scans the annotations in the beans and activate them. In short what we can say is that <context:component-scan> does what <context:annotation-config> does as well as registers the beans to the context
- <context:component-scan>=<context:annotation-config>+Bean Registration
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper
Spring MVC (client and server side) uses
HttpMessageConverters
to negotiate content conversion in an HTTP exchange. If Jackson is on the classpath you already get the default converter(s) provided by Jackson2ObjectMapperBuilder
, an instance of which is auto-configured for you.
The
ObjectMapper
(or XmlMapper
for Jackson XML converter) instance created by default has the following customized properties:MapperFeature.DEFAULT_VIEW_INCLUSION
is disabledDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabled
Spring Boot has also some features to make it easier to customize this behavior.
For example, to enable pretty print, set
spring.jackson.serialization.indent_output=true
. Note that, thanks to the use of relaxed binding, the case of indent_output
doesn’t have to match the case of the corresponding enum constant which is INDENT_OUTPUT
.
Any beans of type
com.fasterxml.jackson.databind.Module
will be automatically registered with the auto-configured Jackson2ObjectMapperBuilder
and applied to any ObjectMapper
instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.
If you want to replace the default
ObjectMapper
completely, either define a @Bean
of that type and mark it as @Primary
, or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder
@Bean
. Note that in either case this will disable all auto-configuration of the `ObjectMapper.
If you provide any
@Beans
of type MappingJackson2HttpMessageConverter
then they will replace the default value in the MVC configuration. Also, a convenience bean is provided of type HttpMessageConverters
(always available if you use the default MVC configuration) which has some useful methods to access the default and user-enhanced message converters.How to customise the Jackson JSON mapper in Spring Web MVC
http://magicmonster.com/kb/prg/java/spring/webmvc/jackson_custom.html
http://stackoverflow.com/questions/32356935/mappingjacksonhttpmessageconverter-not-found-with-spring4
There's a newer version of that class in Spring 4: use
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
(note the '2').@Bean -- doesn't work
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return builder;
}
http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-java-based-config/
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.data.web.PageableArgumentResolver" />
</mvc:argument-resolvers>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Configuration
@EnableWebMvc
@ComponentScan("com.swayam.demo.web.rest")
@PropertySource("classpath:jdbc.properties")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
converters.add(new MappingJackson2HttpMessageConverter(jackson2ObjectMapperBuilder.build()));
Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter = new Jaxb2RootElementHttpMessageConverter();
converters.add(jaxb2RootElementHttpMessageConverter);
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfig() {
return new PropertySourcesPlaceholderConfigurer();
}
}
http://stackoverflow.com/questions/7854030/configuring-objectmapper-in-spring
Using Spring Boot (1.2.4) and Jackson (2.4.6) the following annotation based configuration worked for me.
@Configuration
public class JacksonConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
return mapper;
}
}
https://objectpartners.com/2015/12/07/avoiding-a-common-spring-annotation-configuration-mistake/
@Bean
public MappingJackson2HttpMessageConverter converter(@Qualifier("jsonMapper") final ObjectMapper objectMapper) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper);
return converter;
}
@Bean
public ObjectMapper jsonMapper() {
return new JacksonObjectMapper();
}
https://www.tutorialspoint.com/spring/spring_bean_scopes.htm
When defining a <bean> in Spring, you have the option of declaring a scope for that bean. For example, To force Spring to produce a new bean instance each time one is needed, you should declare the bean's scope attribute to be prototype. Similar way if you want Spring to return the same bean instance each time one is needed, you should declare the bean's scope attribute to be singleton.
you can use Method Injection in scenarios where bean lifecycles are different i.e. you want to inject a non-singleton bean inside a singleton bean. For those of you who are not aware of Method Injection, it allows you to inject methods instead of objects in your class. Method Injection is useful in scenarios where you need to inject a smaller scope bean in a larger scope bean. For example, you have to inject a prototype bean inside an singleton bean , on each method invocation of Singleton bean. Just defining your bean prototype, does not create new instance each time a singleton bean is called because container creates a singleton bean only once, and thus only sets a prototype bean once. So, it is completely wrong to think that if you make your bean prototype you will get new instance each time prototype bean is called.
The second approach is to use Spring AOP Scoped proxies which injects a new validator instance each time RequestProcessor bean is called. To make it work, the only change you have to do is to specify proxyMode in Validator class.
@Scope
(proxyMode = ScopedProxyMode.TARGET_CLASS, value =
"prototype"
)
There are four possible values for proxyMode attribute.I have used TARGET_CLASS which creates a class based proxy. This mode requires that you have CGLIB jar in your classpath.
Let say there are two classes, namely SingletonBean and PrototypeBean class, where prototype bean reference is kept inside the singleton bean. And as the name suggests, SingletonBean is specified with "singleton" scope and "prototype" scope for PrototypeBean. Now if we access the singleton bean using the application context, it will create single instance all times. However if we access the prototype bean reference using the singleton bean reference it will also show single instance all times because it has been wrapped inside the singleton bean, which is an expected behaviour under singleton pattern scenario. But we specified the prototype scope in PrototypeBean and if we wanted to return a new PrototypeBean object every time when we access using the singleton reference(getPrototypeBean()) then we need to specify the prototype bean additionally using
or @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) as annotation.
or @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) as annotation.
The Spring IoC container manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject (for example) an HTTP request scoped bean into another bean of a longer-lived scope, you may choose to inject an AOP proxy in place of the scoped bean. That is, you need to inject a proxy object that exposes the same public interface as the scoped object but that can also retrieve the real target object from the relevant scope (such as an HTTP request) and delegate method calls onto the real object.
http://stackoverflow.com/questions/37944677/cache-interceptor-call-is-ignored
http://www.nurkiewicz.com/2013/01/cacheable-overhead-in-spring.html
Your comment about JdkDynamixAopProxy and looking at the code makes me think that the method you have annotated with
@Cacheable
is in a concrete class. And for the annotation on a concrete class to exhibit proper behavior; you need to enable the cglib proxying in your application.
This can be done by adding proxy target class parameter to your cache annotation driven tag.
<cache:annotation-driven proxy-target-class="true"/>
If you dont want to enable class based proxying for your overall application; you can specify the behavior for a particular class by annotating it with this annotation:
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public interface Calculator { int identity(int x); } public class PlainCalculator implements Calculator { @Cacheable("identity") @Override public int identity(int x) { return x; } }
http://shengwangi.blogspot.com/2015/12/most-used-hibernate-properties-during-development.html
There is also no need for hibernate.hbm2ddl.auto. Spring boot will also auto detect if the database used is a embedded one, like HSQL, H2 or Derby, or external database. If a embedded database is used, default is create-drop. Otherwise for external database, default is none. (No tables will be auto created). You can set this behavior in spring boot's configuration file application.properties with spring.jpa.hibernate.ddl-auto= create, for example.
Other hibernate properties can be se with prefix 'spring.jpa.properties.' , such as add following lines in /src/main/resources/application.properties
1
2
3
4
5
| # hibernate special properties, with prefix "spring.jpa.properties." spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect spring.jpa.properties.hibernate.c3p0.min_size=3 spring.jpa.properties.hibernate.c3p0.max_size=10 spring.jpa.properties.hibernate.show_sql= true |
1.1 Print out Hibernate created SQL
hibernate.show_sql = true
1.2 Automatic create tables according to entities
hibernate.hbm2ddl.auto = create
Change to create-drop if you want to drop the created table when application over. Useful for prototype and testing.
1.3 Run SQL scripts at beginning of application
hibernate.hbm2ddl.import_files = /path/of/sqlfile
This's most used to insert some test data before unit test case running.
1.4 Use c3p0 connection pool
hibernate.c3p0.min_size=5 // minimum connections in pool
hibernate.c3p0.max_size=20 // maximum connections in pool
hibernate.c3p0.timeout=1800 // time out to remove idle connection. In seconds
hibernate.c3p0.max_statements=50 // cache prepared statements
hibernate.c3p0.idle_test_period=3000 // how often to validate a connection. In seconds.
http://stackoverflow.com/questions/30118683/how-to-log-sql-statements-in-spring-boothibernate.c3p0.max_size=20 // maximum connections in pool
hibernate.c3p0.timeout=1800 // time out to remove idle connection. In seconds
hibernate.c3p0.max_statements=50 // cache prepared statements
hibernate.c3p0.idle_test_period=3000 // how often to validate a connection. In seconds.
This works for stdout too:
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
To log values:
spring.jpa.properties.hibernate.type=trace
Just add this to
application.properties
.
try using this in your properties file:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
http://docs.spring.io/autorepo/docs/spring-boot/current/reference/html/boot-features-profiles.html
Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments. Any
@Component
or @Configuration
can be marked with @Profile
to limit when it is loaded:@Configuration @Profile("production") public class ProductionConfiguration {
spring.profiles.active=dev,hsqld
or specify on the command line using the switch
http://stackoverflow.com/questions/12576156/reading-a-list-from-properties-file-and-load-with-spring-annotation-value--spring.profiles.active=dev,hsqldb
.my.list.of.strings=ABC,CDE,EFG
@Value("#{'${my.list.of.strings}'.split(',')}")
private List<String> myList;
Assuming your properties file is loaded correctly with the following:
my.list.of.strings=ABC,CDE,EFG
Since Spring 3.0, you can add a line like
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean" />
to your
applicationContext.xml
(or where you configure things). As Dmitry Chornyi points out in a comment, Java based configuration looks like:@Bean public ConversionService conversionService() {
return new DefaultConversionService();
}
This activates the new configuration service which supports converting
String
to Collection
types. If you do not activate this configuration service, Spring falls back on its legacy property editors as configuration services, which do not support this kind of conversion.
Converting to collections of other types works, too:
@Value("${my.list.of.ints}")
private List<Integer> myList
will work with a line like
my.list.of.ints= 1, 2, 3, 4
http://blog.codeleak.pl/2015/09/placeholders-support-in-value.htmlTo inject complex properties using
@Value
annotation you need to make a Spring’s ConversionService
available in the application context . Registering default conversion service gives the possibility to inject lists, arrays and other convertible types. Usually, in the Spring’s servlet context the ConversionService
will be registered (e.g. via @EnableWebMvc
), but in order to manually register it you can use the following code.ConfigurationProperties
http://www.jianshu.com/p/df57fefe0ab7
https://dzone.com/articles/spring-boot-configurationproperties-1
prefix = "prefix") (
public class SampleProperty {
private String stringProp1;
private String stringProp2;
99) (
0) (
private Integer intProp1;
private List<String> listProp;
private Map<String, String> mapProp;
...
}
https://blog.synyx.de/2016/11/bean-x-of-type-y-is-not-eligible-for-getting-processed-by-all-beanpostprocessors/
spring @Cacheable with Ehcache, spel find null for valid object
That’s not a work-around, that’s the solution. SpEL cannot access arguments by name if that information is not available. You need at least
-g:vars
My pom compiler config had debug:false, added debug:true and it works after maven build, updated post. Have jdk=7u55(IcedTea 2.4.7)64bit on linux
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
argument name | evaluation context | Name of any of the method arguments. If for some reason the names are not available (e.g. no debug information), the argument names are also available under the #a<#arg> where #arg stands for the argument index (starting from 0). |
@CacheEvict on Multiple Objects Using Annotations
http://stackoverflow.com/questions/11854408/ehcache-cacheevict-on-multiple-objects-using-annotations
The @Caching annotation can be used to combine multiple annotations of the same type such as @CacheEvict or @CachePut, this is the example from the Spring documentation
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value="secondary", key="#p0") })
You can do one of two things
@CacheEvict(value = "tacos", allEntries = true)
removeTacos(Set<String> tacoIds)
which is not so bad if tacos are read a lot more than they are removed
OR
removeTacos(Set<String> tacoIds) {
for (String tacoId : tacoIds) {
getTacoService().removeTaco(tacoId);
}
}
by calling the service (proxy) you invoke the cache eviction.
http://stackoverflow.com/questions/37218544/spring-caching-spring-repository-evict-multiple-keys@Cacheable
public User getByUsername(String username);
@Cacheable
public User getByEmail(String email);
@Caching(evict = {
@CacheEvict(cacheNames = "Users", key="#user.name"),
@CacheEvict(cacheNames = "Users", key="#user.email")
})
User save(User user);
You could also try, as another optimization, to combine the
@CachePut
annotation with the 2 @CacheEvict
annotations in this case, which could restore the cache based on the new, updated entity, something like...@Caching(
evict = {
@CacheEvict(cacheNames = "Users", key="#a0.name", beforeInvocation = true),
@CacheEvict(cacheNames = "Users", key="#a0.email", beforeInvocation = true)
},
put = {
@CachePut(cacheNames = "Users", key="#result.name"),
@CachePut(cacheNames = "Users", key="#result.email")
}
)
User save(User user);
NOTE: notice the user of the
spring-data cacheablebeforeInvocation
attribute on the @CacheEvict
annotations along with the @CachePuts
CacheAspectSupport.execute
SpringCacheAnnotationParser.parseCacheAnnotations
http://stackoverflow.com/questions/39432764/info-warnings-about-multiple-modules-in-spring-boot-what-do-they-mean
There is a whole section about in the documents:
Basically if you are using the generic interfaces (e.g. CrudRepository) then Spring won't know if you want that repository to be backed on the spring-mongodb or spring-redis data modules.
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.multiple-modules
Strict configuration requires details on the repository or the domain class to decide about Spring Data module binding for a repository definition:
- If the repository definition extends the module-specific repository, then it’s a valid candidate for the particular Spring Data module.
- If the domain class is annotated with the module-specific type annotation, then it’s a valid candidate for the particular Spring Data module
AmbiguousRepository
and AmbiguousUserRepository
extend only Repository
and CrudRepository
in their type hierarchy. While this is perfectly fine using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.
The last way to distinguish repositories is scoping repository base packages. Base packages define the starting points for scanning for repository interface definitions which implies to have repository definitions located in the appropriate packages. By default, annotation-driven configuration uses the package of the configuration class. The base package in XML-based configuration is mandatory.
@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
interface Configuration { }
https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/main/java/example/springdata/jpa/caching/CachingUserRepository.java
https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/test/java/example/springdata/jpa/caching/CachingRepositoryTests.java
@Cacheable("byUsername") User findByUsername(String username);
@Cacheable
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
@Cacheable(cacheNames="books", key="#isbn") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="#isbn.rawNumber") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="T(someType).hash(#isbn)") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
cache timeout
http://stackoverflow.com/questions/27968157/expiry-time-cacheable-spring-boot
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/htmlsingle/#cache-specific-config
How can I set the TTL/TTI/Eviction policy/XXX feature?
Directly through your cache provider. The cache abstraction is… well, an abstraction not a cache implementation. The solution you are using might support various data policies and different topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.
redis cache
https://my.oschina.net/wnjustdoit/blog/644311
扩展基于注解的spring缓存,使缓存有效期的设置支持方法级别-redis篇
<property name="defaultExpiration" value="3600"/> <!-- 多个缓存有效期,一般的单个工程可以省略此项 --> <property name="expires"> <map> <entry key="caiya_a" value="1800"/> </map> </property>
http://stackoverflow.com/questions/34893279/spring-data-redis-expire-key
http://stackoverflow.com/questions/34201135/spring-redis-read-configuration-from-application-properties-file
@Configuration
@PropertySource("application.properties")
public class SpringSessionRedisConfiguration {
@Value("${redis.hostname}")
private String redisHostName;
@Value("${redis.port}")
private int redisPort;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHostName);
factory.setPort(redisPort);
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
return redisCacheManager;
}
}
http://stackoverflow.com/questions/14072380/cacheable-key-on-multiple-method-arguments@Cacheable(value="bookCache",
key="{ #root.methodName, #isbn?.id, #checkWarehouse }")
public Book findBook(ISBN isbn, boolean checkWarehouse)
...
@Cacheable(value="bookCache",
key="{ #root.methodName, #asin, #checkWarehouse }")
public Book findBookByAmazonId(String asin, boolean checkWarehouse)
@Cacheable(value="bookCache", key="T(java.util.Objects).hash(#p0,#p1, #p2)"
http://javakart.blogspot.com/2012/12/spring-data-redis-hello-world-example.html
@Autowired
private
RedisTemplate<String,User> redisTemplate;
@Override
public
void
put(User user) {
redisTemplate.opsForHash()
.put(user.getObjectKey(), user.getKey(), user);
}
@Override
public
void
delete(User key) {
redisTemplate.opsForHash().delete(key.getObjectKey(), key.getKey());
}
@Override
public
User get(User key) {
return
(User) redisTemplate.opsForHash().get(key.getObjectKey(),
key.getKey());
}
@Override
public
List<User> getObjects() {
List<User> users =
new
ArrayList<User>();
for
(Object user : redisTemplate.opsForHash().values(User.OBJECT_KEY) ){
users.add((User) user);
}
return
users;
}
https://github.com/caseyscarborough/spring-redis-caching-example/blob/master/src/main/java/com/caseyscarborough/spring/redis/config/CacheConfig.java
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
http://docs.spring.io/spring-data/redis/docs/current/reference/html/
public class TimeToLiveOnProperty {
@Id
private String id;
@TimeToLive
private Long expiration;
}
http://stackoverflow.com/questions/36623208/spring-redistemplate-after-8-calls-method-keys-hangs-up
Assuming you're using Jedis with pooling, you run into an exhaustion of the underlying connection pool.
Each call to
redisTemplate.getConnectionFactory().getConnection()
allocates a new connection from the connection pool. Do you call connection.close()
?. If not, the pool gets exhausted. The pools starts to block your request (hoping another thread will return a connection so it can be used by the thread which requests a connection).
I also change redisTemplate.getConnectionFactory().getConnection().keys(...) to redisTemplate.keys(..)
http://www.jianshu.com/p/a78de210a947
- RedisTemplate对象默认使用jdkSerializer实现序列化,如果想要更换序列化的实现方式,例如使用json实现value的序列化,可以进行如下配置
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(ObjectMapper objectMapper) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
@Bean
RedisTemplate<String, Object> objRedisTemplate(JedisConnectionFactory connectionFactory,
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
return redisTemplate;
}
https://segmentfault.com/a/1190000005885205
opsForValue() | ValueOperations<K,V> | 描述具有简单值的条目 |
opsForList() | ListOperations<K,V> | 操作具有list值的条目 |
opsForSet() | SetOperations<K,V> | 操作具有set值的条目 |
opsForZSet() | ZSetOperations<K,V> | 操作具有ZSet值(排序的set)的条目 |
opsForHash() | HashOperations<K,HK,VH> | 操作具有hash值的条目 |
boundValueOps(K) | BoundValueOperations<K,V> | 以绑定指定key的方式,操作具有简单值的条目 |
boundListOps(K) | BoundListOperations<K,V> | 以绑定指定key的方式,操作具有list的条目 |
boundSetOps(K) | BoundSetOperations<K,V> | 以绑定指定key的方式,操作具有set的条目 |
boundZSet(K) | BoundZSetOperations<K,V> | 以绑定指定key的方式,操作具有ZSet(排序的set)的条目 |
boundHashOps(K) | BoundHashOperations<K,V> | 以绑定指定key的方式,操作具有hash值的条目 |
Cache
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
Sometimes, a method might not be suitable for caching all the time (for example, it might depend on the given arguments). The cache annotations support such functionality through the
condition
parameter which takes a SpEL
expression that is evaluated to either true
or false
. If true
, the method is cached - if not, it behaves as if the method is not cached, that is executed every time no matter what values are in the cache or what arguments are used
In addition the
condition
parameter, the unless
parameter can be used to veto the adding of a value to the cache. Unlike condition
, unless
expressions are evaluated after the method has been called. Expanding on the previous example - perhaps we only want to cache paperback books:@Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.hardback") public Book findBook(String name)
The cache abstraction supports
java.util.Optional
, using its content as cached value only if it present. #result
always refers to the business entity and never on a supported wrapper so the previous example can be rewritten as follows:@Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.hardback") public Optional<Book> findBook(String name)
Note that
result
still refers to Book
and not Optional
.@Cacheable(value = "reservationsCache") public List<Reservation> getReservationsForRestaurant( Restaurant restaurant ) { }
However, it is also easy to lose track of the actual cache key that is being used. The above call uses a default key generation strategy that creates a SimpleKey that consists of all the parameters with which the method was called. This requires the parameters to have a decent hashCode()/equals() implementation, which is not usually a problem in itself except that the performance of hashCode() and equals() also impacts the performance of cache retrieval. Again, that's usually not much of an issue.
A more important caveat here is that the parameters themselves become an integral part of the cache key, and that can have an unwanted impact on the actual heap size being used as the cache key is kept on the heap as well. Consider our example: we use a Restaurant as the cache key. However the restaurant is a complex domain entity holding lots of data and having several collections of related entities. All this data is kept alive as long as the cache entry exists and keeps taking up room on the heap, even if it is no longer relevant.
@Cacheable(value = "reservationsCache", key = "#restaurant.id") public List<Reservation> getReservationsForRestaurant( Restaurant restaurant ) { }
In short: you should not only pay attention to the unicity of your cache keys, but also to the size of the actual cache key being generated. Use the key property or a custom key generator to have more fine-grained control over your cache keys.
Using @Cacheable combines both looking in the cache and storing the result. Using @CachePut and @CacheEvict annotations gives you more fine-grained control. You can also use the @Caching annotation to combine multiple cache related annotations on a single method. Avoid combining @Cacheable and @CachePut on the same method, as the behavior can be quite confusing.
https://docs.datastax.com/en/developer/java-driver/2.1/manual/logging/#logging-query-latencies
https://docs.datastax.com/en/cassandra/2.1/cassandra/configuration/configLoggingLevels_r.html
QueryLogger queryLogger = QueryLogger.builder(cluster)
.withConstantThreshold(...)
.withMaxQueryStringLength(...)
.build();
http://stackoverflow.com/questions/41220442/cassandra-query-logging-through-spring-configurationhttp://docs.spring.io/spring-data/cassandra/docs/2.0.x/reference/html/
https://lostechies.com/ryansvihla/2016/04/07/logging-the-generated-cql-from-the-spark-cassandra-connector/
<logger name=”com.datastax.driver.core.RequestHandler” level=”TRACE”/>
Spring Data Converter
https://gist.github.com/harlanji/1179718
Need to call
afterPropertiesSet()
@Override
@Bean(name = "mongoCTGTEmplate")
public MongoTemplate mongoTemplate() throws Exception {
MongoTemplate m_ = new MongoTemplate(this.mongo(), databaseCTG);
MappingMongoConverter mmc = (MappingMongoConverter) m_.getConverter();
mmc.setCustomConversions(this.customConversions());
mmc.afterPropertiesSet();//\\
return m_;
}
http://stackoverflow.com/questions/21827548/spring-get-current-applicationcontext WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
MyClass myBean = context.getBean(MyClass.class);
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
@Autowired
private ApplicationContext appContext;
or implement this interface: ApplicationContextAware
https://dzone.com/articles/spring-configuration-andthere is one alternate way to inject dependency that is not documented well, it is to just take the dependency as a `@Bean` method parameter this way:
@Bean public Foo foo(Bar bar1) { return new Foo(bar1); }
@Bean public Foo foo(@Qualifier("bar1") Bar bar1) { return new Foo(bar1); }
https://github.com/ulisesbocchio/jasypt-spring-boot
http://www.seropian.eu/2015/05/spring-boot-jasypt-easy-encrypted-properties.html
https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java
org.springframework.context.annotation.ConfigurationClassParser
org.springframework.context.annotation.ConfigurationClassParser.processPropertySource(AnnotationAttributes)
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
To fix it, create a “none static setter” to assign the injected value for the static variable. For example :
@Component
public class GlobalValue {
public static String DATABASE;
@Value("${mongodb.db}")
public void setDatabase(String db) {
DATABASE = db;
}
}
http://stackoverflow.com/questions/38731419/how-to-add-servlet-filter-using-spring-factories
@Bean
public FilterRegistrationBean contextFilterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
RequestContextFilter contextFilter = new RequestContextFilter();
registrationBean.setFilter(contextFilter);
registrationBean.setOrder(1);
return registrationBean;
}
3) create file src/main/resources/META-INF/spring.factories and add:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.test.FilterConfig
4) publish/install your jar and include it as dependency of your Spring Boot application.
After this, FilterConfig should load automatically in every Spring Boot app you add the dependency where
http://stackoverflow.com/questions/6850344/spring-integration-or-apache-http-client@EnableAutoConfiguration
is used (I.E. by using annotation @SpringBootApplication
).
As the others have mentioned both Spring RestTemplate and Jersey Rest Client will do the job. I have used both. Both them work great with Jackson and IIRC they will automatically use it if found (spring for sure).
There is one advantage I like about Spring RestTemplate is that you can plugin Commons HTTP as the transport. So if you had some weird headers, cookies, timeout, threading you can configure Commons HTTP and then put it into the RestTemplate.
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
CommonsClientHttpRequestFactory f = new CommonsClientHttpRequestFactory();
f.setReadTimeout(120 * 1000);
The point is if you are thinking about using Commons HTTP Client then as @Skaffman says RestTemplate is a no-brainer over something more complicated!
- Less boilerplate code
- More cohesive exceptions handling (e.g. JDBC drivers checked exceptions are translated to meaningful runtime exceptions)
- Easier and uniform configuration (almost everything can be configured in Spring context files)
- Automatized resource management (like, for instance, closing DB connections)
Spring's central class for synchronous client-side HTTP access. It simplifies communication with HTTP servers, and enforces RESTful principles. It handles HTTP connections, leaving application code to provide URLs (with possible template variables) and extract results.
Note: by default the RestTemplate relies on standard JDK facilities to establish HTTP connections. You can switch to use a different HTTP library such as Apache HttpComponents, Netty, and OkHttp through the
HttpAccessor.setRequestFactory(org.springframework.http.client.ClientHttpRequestFactory)
property.http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-restclient.html
hibernate-validator
http://stackoverflow.com/questions/21444878/spring-data-solr-how-to-get-suggestions
https://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
https://github.com/spring-projects/spring-boot/search?l=Maven+POM&q=hibernate-validator&utf8=%E2%9C%93
https://github.com/christophstrobl/spring-data-solr-showcase
FacetPage<Product> result = productService.autocompleteNameFragment(query, pageable);
http://projects.spring.io/spring-data-solr/
https://github.com/spring-projects/spring-data-solr
https://github.com/spring-projects/spring-data-solr-examples
http://docs.spring.io/spring-data/solr/docs/current/reference/html/
Note, that the intermediate repository interface is annotated with @NoRepositoryBean . Make sure you add that annotation to all repository interfaces that Spring Data should not create instances for at runtime. |
The preceding approach is not feasible when you want to add a single method to all your repository interfaces. To add custom behavior to all repositories, you first add an intermediate interface to declare the shared behavior.
@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID> {
void sharedCustomMethod(ID id);
}
Now your individual repository interfaces will extend this intermediate interface instead of the
Repository
interface to include the functionality declared. Next, create an implementation of the intermediate interface that extends the persistence technology-specific repository base class. This class will then act as a custom base class for the repository proxies.Use
@Score
to automatically add projection on document score
In order to load score information of a query result, a field annotated with
@Score
annotation could be added, indicating the property holding the documents score. @Score
private Float score;
On top of the
CrudRepository
there is a PagingAndSortingRepository
abstraction that adds additional methods to ease paginated access to entities:need @Id
@SolrDocument
@Bean
public SolrClient solrClient() {
EmbeddedSolrServerFactory factory = new EmbeddedSolrServerFactory("classpath:com/acme/solr");
return factory.getSolrServer();
}
@Bean
public SolrOperations solrTemplate() {
return new SolrTemplate(solrClient());
}
https://dzone.com/articles/using-spring-profiles-and-java@Test public void testProfileActiveUsingSystemProperties() { System.setProperty("spring.profiles.active", "test1"); ApplicationContext ctx = new ClassPathXmlApplicationContext("profiles-config.xml"); Person person = ctx.getBean("employee", Person.class); String firstName = person.getFirstName(); assertEquals("John", firstName); }
@Test public void testAnnotationConfigApplicationContextThatWorks() { // Can register a list of config classes AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.getEnvironment().setActiveProfiles("test1"); ctx.register(Test1ProfileConfig.class, Test2ProfileConfig.class); ctx.refresh(); Person person = ctx.getBean("employee", Person.class); String firstName = person.getFirstName(); assertEquals("John", firstName); }https://dzone.com/articles/using-spring-profiles
SpringJUnit4ClassRunner.class) (
locations = { "classpath*:META-INF/mySpringContext.xml" }) (
context.getEnvironment().setActiveProfiles(activeProfiles);
The @Profile annotation may contain more complex expressions than just the profile name. It could be a list of names:
Or even negative expression:
http://www.java-allandsundry.com/2013/09/spring-4-conditional.html
@Bean
public
CustomerService customerService() {
if
(System.getProperty(
"servicedefault"
)!=
null
) {
return
new
CustomerServiceImpl1();
}
return
new
CustomerServiceImpl2();
}
@Bean
@ConditionalOnSystemProperty
(value=
"servicedefault"
, exists=
false
)
public
CustomerService service2() {
return
new
CustomerServiceImpl2();
}
public
class
OnSystemPropertyCondition
implements
Condition {
@Override
public
boolean
matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map<String, Object> attributes
= metadata.getAnnotationAttributes(ConditionalOnSystemProperty.
class
.getName());
Boolean systemPropertyExistsCheck = (Boolean)attributes.get(
"exists"
);
String systemProperty = (String)attributes.get(
"value"
);
if
((systemPropertyExistsCheck && (System.getProperty(systemProperty) !=
null
)) ||
(!systemPropertyExistsCheck && (System.getProperty(systemProperty) ==
null
))) {
return
true
;
}
return
false
;
}
}
To be able to have a dynamic registration of jobs at runtime and gain direct access to the org.quartz.Scheduler, you must use a bean reference to this SchedulerFactoryBean(). This allows you to:
- Create new jobs.
- Create new triggers.
- Control the entire Scheduler.
- Monitor the Scheduler
Note: Click here for SchedulerFactoryBean API. Use the org.quartz.Scheduler to schedule and unschedule jobs. See link for Scheduler API.
http://www.kubrynski.com/2013/09/injecting-spring-dependencies-into-non.html
public class TaskManager {
@Autowired
private StdSchedulerFactory schedulerFactory;public void manageTasks(){
try {
//gets a reference from Quartz Scheduler
scheduler = (StdScheduler) this.schedulerFactory.getScheduler();
//manage jobs using Quartz API
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("myJob", "group1")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
// add Job
scheduler.addJob(job, true);
// define a schedule
scheduler.scheduleJob(job, trigger);
scheduler.start();
// pause Job
scheduler.pauseJob(job.getKey());
scheduler.unscheduleJob(trigger.getKey());
scheduler.deleteJob(job.getKey());
scheduler.shutdown();
} catch (SchedulerException e){
e.printStackTrace();
}
}}
How do I manually autowire a bean with Spring?
http://stackoverflow.com/questions/11965600/how-do-i-manually-autowire-a-bean-with-spring
B bean = new B();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean( bean );
factory.initializeBean( bean, "bean" );
The first method will process
@Autowire
fields and methods (but not classic properties). The second method will invoke post processing (@PostConstruct
and any defined BeanPostProcessor
s).
Application context can be obtained in a bean if it implements
@AutowiredApplicationContextAware
interfaceprivate AutowireCapableBeanFactory beanFactory;
https://spring.io/blog/2011/08/09/what-s-a-factorybean
A
FactoryBean
is a pattern to encapsulate interesting object construction logic in a class. It might be used, for example, to encode the construction of a complex object graph in a reusable way. Often this is used to construct complex objects that have many dependencies. It might also be used when the construction logic itself is highly volatile and depends on the configuration. A FactoryBean
is also useful to help Spring construct objects that it couldn’t easily construct itself. For example, in order to inject a reference to a bean that was obtained from JNDI, the reference must first be obtained. You can use the JndiFactoryBean
to obtain this reference in a consistent way. You may inject the result of a FactoryBean
’s getObject()
method into any other property.http://stackoverflow.com/questions/25012051/difference-between-defining-queries-in-the-repository-interface-or-entity-class
Generally speaking we recommend defining the queries at the repository interface for a very simple reason: it's conceptually closer to the query execution. Also,
@Query
has a few advanced options when it comes to the additional queries that e.g. need to be triggered to implement pagination.
However, if you want to re-use the query definition on multiple query methods, using a named query is still a reasonable option.
A factory bean is a bean that serves as a factory for creating other beans within the IoC container. Conceptually, a factory bean is very similar to a factory method, but it is a Spring-specific bean that can be identified by the Spring IoC container during bean construction and can be used by container to instantiate other beans.
Factory beans are mostly used to implement framework facilities. Here are some examples:
- When looking up an object (such as a data source) from JNDI, you can use
JndiObjectFactoryBean
. - When using classic Spring AOP to create a proxy for a bean, you can use
ProxyFactoryBean
. - When creating a Hibernate session factory in the IoC container, you can use
LocalSessionFactoryBean
.
CacheableOperation parseCacheableAnnotation
How Cacheable generate key
org.springframework.cache.interceptor.CacheAspectSupport.CacheOperationContext.generateKey(Object)
org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.createEvaluationContext(Collection<? extends Cache>, Method, Object[], Object, Class<?>, Object, BeanFactory)
org.springframework.context.expression.CachedExpressionEvaluator.getExpression(Map<ExpressionKey, Expression>, AnnotatedElementKey, String)
SpelExpressionParser parser;
org.springframework.context.expression.CachedExpressionEvaluator.getExpression(Map<ExpressionKey, Expression>, AnnotatedElementKey, String)
How Cacheable generate key
org.springframework.cache.interceptor.CacheAspectSupport.CacheOperationContext.generateKey(Object)
org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.createEvaluationContext(Collection<? extends Cache>, Method, Object[], Object, Class<?>, Object, BeanFactory)
org.springframework.context.expression.CachedExpressionEvaluator.getExpression(Map<ExpressionKey, Expression>, AnnotatedElementKey, String)
SpelExpressionParser parser;
org.springframework.context.expression.CachedExpressionEvaluator.getExpression(Map<ExpressionKey, Expression>, AnnotatedElementKey, String)