Wednesday, July 8, 2015

Spring Miscs



Spring EL:
http://conkeyn.iteye.com/blog/2354644
  1.     // shared param discoverer since it caches data internally  
  2.     private final ParameterNameDiscoverer paramNameDiscoverer =  
  3.             new DefaultParameterNameDiscoverer();  


Create bean conditionally:
http://www.cubearticle.com/articles/framework/spring/spring_conditional_bean
http://stackoverflow.com/questions/29844271/conditional-spring-bean-creation
public class WebServiceCondition implements Condition{

    public boolean matches(ConditionContext context, AnnotatedTypeMetadata annoMetaData) {
        Environment env =  context.getEnvironment();
        String webservice = env.getProperty("webservice");
        if(webservice!=null &&  webservice.equals("rest"))
            return true;
        
        return false;
    }
}

Using Spring managed Bean in non-managed object
https://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html
6public interface SpringContextBridgedServices {
7    TaxService getTaxService();
8}
  1. This class should also implement the ApplicationContextAware interface from Spring. The only argument in the method we need to implement from the interface is the argumentApplicationContext. We hold this argument in a static member variable.
  2. Create a static method to return the SpringContextBridgedServices and let this method return the Bean which is managed by Spring. UseapplicationContext.getBean(SpringContextBridgedServices.class) to return it.
  3. Autowire the TaxService and return it in the method we need to implement from theSpringContextBridgedServices method.
12@Component
13public class SpringContextBridge
14        implements SpringContextBridgedServices, ApplicationContextAware {
15
16    private static ApplicationContext applicationContext;
17
18    @Autowired
19    private TaxService taxService; //Autowire the TaxService
20
21    @Override
22    public void setApplicationContext(ApplicationContext applicationContext)
23            throws BeansException {
24        this.applicationContext = applicationContext;
25    }
26
27    /**
28     * A static method to lookup the SpringContextBridgedServices Bean in
29     * the applicationContext. It is basically an instance of itself, which
30     * was registered by the @Component annotation.
31     *
32     * @return the SpringContextBridgedServices, which exposes all the
33     * Spring services that are bridged from the Spring context.
34     */
35    public static SpringContextBridgedServices services() {
36        returnapplicationContext.getBean(SpringContextBridgedServices.class);
37    }
38
39    @Override
40    public TaxService getTaxService() {
41        return taxService; //Return the Autowired taxService
42    }
43}
  • Note 1: It is a possibility to return a Spring managed bean in a static method itself. I choose not to do this, so I have less static methods and can later Mock some of the references Services.
  • Note 2: Eventually you would like to split up the two functionalities. One holding theApplicationContext and returning the SpringContextBridgedServices Bean. The other being the SpringContextBridgedServices Bean itself.

        
TaxService taxService = SpringContextBridge.services().getTaxService();
If you want a more flexible but less controlled way, you can rewrite the SpringContextBridgedServices.
3public interface SpringContextBridgedServicesAlternative {
4
5    <T> T getService(Class<T> serviceType);
6}
Now we can get a service by callingSpringContextBridge.services().getService(TaxService.class). In this alternative we have no control over which Spring managed Bean may be bridged.
http://www.mkyong.com/spring3/spring-value-default-value/
To set a default value in Spring expression, use Elvis operator :
Java
 #{expression?:default value}
 @Value("#{systemProperties['mongodb.port'] ?: 27017}")
 private String mongodbPort;
 @Value("#{aBean.age ?: 21}")
 private int age;
To set a default value for property placeholder :
Java
 ${property:default value}
Few examples :
Java
 //@PropertySource("classpath:/config.properties}")
 //@Configuration
 
 @Value("${mongodb.url:127.0.0.1}")
 private String mongodbUrl;
 
 @Value("#{'${mongodb.url:172.0.0.1}'}")
 private String mongodbUrl;
http://stackoverflow.com/questions/17424739/using-a-request-scoped-bean-outside-of-an-actual-web-request
You can only use request (and session) -scoped beans on the web container thread on which the request is running.
http://www.mkyong.com/spring/spring-request-scope-error-no-thread-bound-request-found/
Spring request scope error : No thread-bound request found
@Component
@Scope("request")
public class PaymentService {

To fix it, register a RequestContextListener listener in web.xml file.
File : web.xml
Markup
<web-app ...>
   <listener>
 <listener-class>
  org.springframework.web.context.request.RequestContextListener
 </listener-class>
   </listener>
</web-app>
http://www.cnblogs.com/jingLongJun/p/4491032.html
在Spring MVC开发中,我们可以很方便的使用Converter来实现对请求参数的处理,比如字符串去空,日期格式化等。

public class StringTrimConverter implements Converter<String, String> {
    public String convert(String source) {
        //如果源字符串不为空则进行转换
        if(source != null){
            //去除源字符串前后空格
            source = source.trim();
            if(source.equals("")){ 
                source = null;
            }
        }
        return source;
    }
}
http://blog.csdn.net/u013485533/article/details/47296361

http://dozer.sourceforge.net/documentation/springintegration.html

http://stackoverflow.com/questions/19737626/how-to-ignore-null-values-using-springframework-beanutils-copyproperties-solve
You can create your own method to copy properties while ignoring null values.
public static String[] getNullPropertyNames (Object source) {
    final BeanWrapper src = new BeanWrapperImpl(source);
    java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

    Set<String> emptyNames = new HashSet<String>();
    for(java.beans.PropertyDescriptor pd : pds) {
        Object srcValue = src.getPropertyValue(pd.getName());
        if (srcValue == null) emptyNames.add(pd.getName());
    }
    String[] result = new String[emptyNames.size()];
    return emptyNames.toArray(result);
}

// then use Spring BeanUtils to copy and ignore null
public static void myCopyProperties(Object, src, Object target) {
    BeanUtils.copyProperties(src, target, getNullPropertyNames(src))
}
Spring Injection with @Resource, @Autowired and @Inject

@Resource’ can also take an optional ‘name’ attribute. This is equivalent to the ‘@Resource’ code above. In this case the field variable name remains ‘party’. There is no equivalent syntax for ‘@Autowired’ or ‘@Inject’. Instead you would have to use a ‘@Qualifier’. This syntax will be covered later.
@Resource(name="person")
private Party party;
Spring Annotation Style Best Practices
  1. Explicitly name your component [@Component(“beanName”)]
  2. Use ‘@Resource’ with the ‘name’ attribute [@Resource(name=”beanName”)]
  3. Avoid ‘@Qualifier’ annotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific ‘@Qualifier’ annotation. This approach makes it simple to inject a group of rule classes into a list that can be used for processing data.
  4. Scan specific packages for components [context:component-scan base-package=”com.sourceallies.person”]. While this will result in more component-scan configurations it reduces the chance that you’ll add unnecessary components to your Spring context.
http://www.javacodegeeks.com/2015/03/using-rx-java-observable-in-a-spring-mvc-flow.html
A better approach is to use the Spring Asynchronous support to return the result back to the user when available from the CompletableFuture, this way not holding up the containers thread:

https://spring.io/guides/gs/async-method/
http://www.baeldung.com/spring-async

    @Async
    public Future<User> findUser(String user) throws InterruptedException {
        System.out.println("Looking up " + user);
        User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
        // Artificial delay of 1s for demonstration purposes
        Thread.sleep(1000L);
        return new AsyncResult<User>(results);
    }

http://www.mkyong.com/spring3/spring-value-default-value/
Spring @Value default value
${property:default value}
@Value("${mongodb.url:127.0.0.1}")
 private String mongodbUrl;
 
 @Value("#{'${mongodb.url:172.0.0.1}'}")
 private String mongodbUrl;

Spring EL
To use SpEL in annotation, you must register your component via annotation. If you register your bean in XML and define @Value in Java class, the @Value will failed to execute.

 @Value("#{itemBean}")
 private Item item;

 @Value("#{itemBean.name}")
 private String itemName;
http://stackoverflow.com/questions/20350961/spring-expression-language-in-custom-annotation
@EventTrigger(value = EventTestModel.class, expression = "new Object[]{arguments[1], arguments[2]}")
        final Map<String, Object> map = new HashMap<String, Object>();
        map.put("age", "125");
        final StandardEvaluationContext itemContext = new StandardEvaluationContext();
        itemContext.setVariables(map);

        final ExpressionParser parser = new SpelExpressionParser();
        // display the value of item.name property
        final String ruleExpression = "new Integer(#age).compareTo(25) >= 0";

        final org.springframework.expression.Expression exp = parser.parseExpression(ruleExpression);

        final Boolean msg = exp.getValue(itemContext, Boolean.class);
Expression exp = parser.parseExpression("name == 'Nikola Tesla'");


http://zachary-guo.iteye.com/blog/1503352
  1. public String handle() {  
  2.     // return "forward:/hello" => 转发到能够匹配 /hello 的 controller 上  
  3.     // return "hello" => 实际上还是转发,只不过是框架会找到该逻辑视图名对应的 View 并渲染  
  4.     // return "/hello" => 同 return "hello"  
  5.     return "forward:/hello";  
Encrypt property values
http://kayalvizhiameen.blogspot.in/2014/04/handling-obfuscated-property-values-in.html
In the spring-beans.xml, we have configured the class 'DecryptPropertyConfigurerfor the properties file 'encryped_db.properties'. So, when the container reads the properties file, instead of calling PropertyPlaceholderConfigurer, it calls our custom call 'DecryptPropertyConfigurer'. In the 'convertProperties' method, we iterate all the values of the property file, decrypt them (used BASE64 decoder) and store it in the java runtime properties. 

Using encrypted passwords with Mule ESB
    <encryption:encryptor-config id="eConf" password-env-name="MULE_ENCRYPTION_PASSWORD" algorithm="PBEWithMD5AndDES"/>
    <encryption:string-encryptor id="stringEnc" config-bean="eConf"/>
    <encryption:encryptable-property-placeholder encryptor="stringEnc" location="classpath:my-environment.properties"/>


http://sourceforge.net/p/jasypt/bugs/28/
First, make sure your placeholder bean and associated beans are declared as static. These have to be initialized early so that the Spring context has access to them for placeholder operations. There may be a way to get around this with some other way of telling the context to load these beans first, but making them static definitely works.
Then, to use a placeholder, use the @Value annotation to do it. Example: @Value=("${prop_name}"). This is working for us. With Spring Boot, you can also use the @ConfigurationProperties(prefix="blah"), but in our experience, the properties did not get decrypted when attempting it this way. Only directly using @Value worked for us.
http://robertmaldon.blogspot.com/2007/06/extending-spring-propertyplaceholdercon.html
http://terasolunaorg.github.io/guideline/5.0.1.RELEASE/en/ArchitectureInDetail/PropertyManagement.html

Environment and properties:
@Autowired
private Environment environment;
in your @Component, and then access the properties through the Environment class:
environment.getProperty("myProp");

http://blog.itmyhome.com/2015/07/spring-interview/#design_patterns_used_in_spring
FileSystemResource和ClassPathResource有何区别?
在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。
在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下

Spring对Java配置的支持是由@Configuration注解和@Bean注解来实现的。由@Bean注解的方法将会实例化、

配置和初始化一个新对象,这个对象将由Spring的IoC容器来管理。@Bean声明所起到的作用与 元素类似。

被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。被@Configuration声明的类可以

通过在同一个类的内部调用@bean方法来设置嵌入bean的依赖关系。

Spring Profile -- doesn't work with @ImportResource
https://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/
@Configuration
@Profile("dev")
public class StandaloneDataConfig {

 @Bean
 public DataSource dataSource() {
  return new EmbeddedDatabaseBuilder()
   .setType(EmbeddedDatabaseType.HSQL)
   .addScript("classpath:com/bank/config/sql/schema.sql")
   .addScript("classpath:com/bank/config/sql/test-data.sql")
   .build();
 }

}
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev");

1@Bean
2@Conditional(SystemPropertyCondition.class)
3public SampleService service1() {
4return new SampleServiceImpl1();
5}
6
7@Bean
8@Conditional(SystemPropertyAbsentCondition.class)
9public SampleService service2() {
10return new SampleServiceImpl2();
11}
SpEL is supported, but Spring resolves the import statement very early on.
When spring is resolving import statements, property placeholders have not yet been resolved.

http://www.intertech.com/Blog/spring-expression-language-a-spring-3-feature-you-may-be-forgetting/
the syntax to designate a Spring expression for evaluation at runtime is #{ “SpEL expression string”}

#{systemProperties['system.propery.flag'] ?: false }
#{itemBean}
#{itemBean.name}
@Value("#{itemBean}")
@Value("#{itemBean.name}")

@Value("#{'Thomas Lake Drive'}")
@Value("#{55121}")
@Value("#{systemProperties['os.arch'].equals('x86') ? winDataSource : unixDataSource}")

METHOD FACTORY WIRING
@Value("#{fileService.createFile()}")
private File file;

STATIC METHOD WIRING
  @Value("#{ T(Math).random()}")
  private double powerLevel;
http://blog.tompawlak.org/useful-things-spring-expression-language-spel
#{otherBean.method().length()}
#{T(java.lang.Integer).MIN_VALUE}
How to avoid exceptions
Instead of a single period (.) you need to precede a period with a question mark (?).
<property name="prop" value="#{otherBean.method()?.toUpperCase()}"/>
#{otherBean.method() != null ? otherBean.method().length() : -1}

Regular Expressions - tru/false
<property name="onlyDigits" value="#{otherMean.method() matches '\d+'}" />

Collection selection can have another syntax.
<property name="topSubjects" value="#{subjectList.?[id gt 111 and id lt 113]}"/>
<property name="mycity" value="#{cities[2]}"/>

Arithmetic Operations
<property name="mrp"value="#{counter.total+25}"/>
spring_spel_oplist












Welcome list
Even u are using javaconfig, still need define welcome-file-list in web,xml. - as there is usually no ROOT.war in production.

Spring Session
Scaling out with Spring Session
curl -H "Cookie: JSESSIONID=A8F4049EE2A2CBDEA70EBD232328610A" http://localhost:8080
Spring Session architecture
The idea behind Spring Session is pretty straight forward:
Create a new Servlet filter
Add the filter to the filter chain of your servlet
Connect the filter to the Redis connection.
https://drissamri.be/blog/2015/05/21/spring-security-and-spring-session/
http://docs.spring.io/spring-session/docs/current-SNAPSHOT/reference/html5/guides/security.html
Instead of using Tomcat’s HttpSession, we are actually persisting the values in Redis. Spring Session replaces theHttpSession with an implementation that is backed by Redis. When Spring Security’sSecurityContextPersistenceFilter saves the SecurityContext to the HttpSession it is then persisted into Redis.
redis-cli keys '*' | xargs redis-cli del
redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e

Caching
Getting an EhCache instance with Spring… intelligently
        @Inject
        private ResourceLoader resourceLoader;

        @Bean
        public CacheManager cacheManager() {
            EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
            try {
                ehCacheCacheManager.setCacheManager(ehcacheCacheManager().getObject());
            } catch (Exception e) {
                throw new IllegalStateException("Failed to create an EhCacheManagerFactoryBean", e);
            }
            return ehCacheCacheManager;
        }

        @Bean
        public FactoryBean<net.sf.ehcache.CacheManager> ehcacheCacheManager() {
            EhCacheManagerFactoryBean bean = new EhCacheManagerFactoryBean();
            bean.setConfigLocation(resourceLoader.getResource("classpath:ehcache.xml"));
            return bean;
        }
http://www.javabeat.net/spring-cache/
http://stackoverflow.com/questions/6730641/how-can-i-set-a-custom-keygenerator-for-spring-cache
For Spring > 3.2, you can use a simple Java class configuration implementing CachingConfigurer:
@EnableCaching(mode = AdviceMode.ASPECTJ)
public class CacheConfig implements CachingConfigurer {

    public KeyGenerator keyGenerator() {
        return new ReflectionBasedKeyGenerator();
    }

    public CacheManager cacheManager() {
        return new RedisCacheManager(redisCacheTemplate);
    }
}
http://stackoverflow.com/questions/15761619/spring-property-placeholders-with-string-concatenation
To concatenate the values parsed from Spring property placeholders, you need to escape their values using single quoutes ('') and wrap the placeholder expressions by a SpEL expression using #{}.
<bean id="myService" class=""com.services.MyService">
  ...
  <property name="endpointAddress" value="#{'${server}' + ':' '${port}' + '${endpoint}'}" />
</bean>
Available caching SpEL evaluation context
NameLocationDescriptionExample
methodNameroot objectThe name of the method being invoked#root.methodName
methodroot objectThe method being invoked#root.method.name
targetroot objectThe target object being invoked#root.target
targetClassroot objectThe class of the target being invoked#root.targetClass
argsroot objectThe arguments (as array) used for invoking the target#root.args[0]
cachesroot objectCollection of caches against which the current method is executed#root.caches[0].name
argument nameevaluation contextName of any of the method argument. If for some reason the names are not available (ex: no debug information), the argument names are also available under the a<#arg> where #arg stands for the argument index (starting from 0).iban or a0 (one can also use p0 or p<#arg> notation as an alias).
resultevaluation contextThe result of the method call (the value to be cached). Only available in unless expressions,cache put expressions (to compute the key), or cache evict expressions (whenbeforeInvocation is false).#result
// create an array of integers
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));

// create parser and set variable 'primes' as the array of integers
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext ctx = new StandardEvaluationContext();
ctx.setVariable("primes", primes);
Now, if we want to narrow the list and get all the prime numbers that are > 10, we can use the ?[]selection operator. The statement would be this one:
Expression expression = parser.parseExpression("#primes.?[#this>10]");
List<Integer> primesGreaterThanTen = (List<Integer>) expression.getValue(ctx);
As you can see, the expression to be evaluated is #primes.?[#this > 10]. How does it work ?
  • #primes refers to the primes list.
  • The ?[] selection operator matches every object i in the primes list which is not null and which matches the criteria, given in the brackets. In our example, the criteria is #this > 10#this refers to the current evaluation object, which in our example would be the object from the list that is being checked at the moment for not-null and > 10.
The result from the evaluation will be a list, containing:
[11, 13, 17]

A SpEL context can have a #root variable. Let's have this simple class:
public class SomeCustomObject {
    public int stringLength(String input) {
        if (input == null) return 0;
        return input.length();
    }
}
and define a instance of our SomeCustomObject as the #root variable.
SomeCustomObject someObject = new SomeCustomObject();
context.setRootObject(someObject);
This will create the someObject variable a root object for the SpEL context.
A simple example with the #root variable.
String name = "kocko";
ctx.setVariable("name", kocko);
String statement = "#root.stringLength(#kocko) == 5";
Expression expression = parser.parseExpression(statement);

boolean result = expression.getValue(context, Boolean.class);
The result variable will be evaluated as true.
What is the power of the #root ?
Through a single root object, you can expose a comprehensive, custom environment to your expressions, for example custom utility methods and/or variables.
http://stackoverflow.com/questions/13461985/classcastexception-proxy-cannot-be-cast-to-using-aop
 if your bean implements some interface then Spring by default will create proxy based on this interface.
Also you can change proxying mechanism for Spring AOP if you want to create proxy for target class. This is described here in reference documentation.

8.6 Proxying mechanisms

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice).
If the target object to be proxied implements at least one interface then a JDK dynamic proxy will be used. All of the interfaces implemented by the target type will be proxied. If the target object does not implement any interfaces then a CGLIB proxy will be created.
If you want to force the use of CGLIB proxying (for example, to proxy every method defined for the target object, not just those implemented by its interfaces) you can do so. However, there are some issues to consider:
  • final methods cannot be advised, as they cannot be overriden.
  • You will need the CGLIB 2 binaries on your classpath, whereas dynamic proxies are available with the JDK. Spring will automatically warn you when it needs CGLIB and the CGLIB library classes are not found on the classpath.
  • The constructor of your proxied object will be called twice. This is a natural consequence of the CGLIB proxy model whereby a subclass is generated for each proxied object. For each proxied instance, two objects are created: the actual proxied object and an instance of the subclass that implements the advice. This behavior is not exhibited when using JDK proxies. Usually, calling the constructor of the proxied type twice, is not an issue, as there are usually only assignments taking place and no real logic is implemented in the constructor.
<aop:config proxy-target-class="true">

<aop:aspectj-autoproxy proxy-target-class="true"/>

https://my.oschina.net/qq596392912/blog/714312

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts