Skip to main content

Posts

Inside spring framework from source code (1)

The spring could be most popular java framework in this world. It had been born at 2002 which is even earlier than Adobe Flex (dead already). Spring source code provided a very elegant way about how to organize your code and define the Apis.  As java developer, all of us should spend time to read source code Spring and get deeply know how to write the solid and high quality code. I am trying to summarize what I got when I review the code and provide a quick guide to understand the code easily. Hope I can finish this giant project. First of all, if we fork the source code from  https://github.com/spring-projects/spring-framework  it is simple to figoure the modules dep from gradle file. For easy purpose, I draw the diagram to represent the dependencies.  The black line is for compile dep and yellow one is for optional dep (just ignore it at very first begging to keep everything simple). Add caption Let's go start from spring-core and spring-beans on the nex...

The practical way to run unittest at parallel and generate the overall test report

The model build tools like gradle/maven provided a pretty easy way to run unit test and generate test summary. Also, gradle support to run unit test concurrently which improved performance a lot. One of project is converting from ANT build to Gradle. However, one challenge of current project can't use gradle's multiple thread to run tests because some of test cases access the same database with conflict and can't run them at the same time.  The existing ant solution was trying to group all tests as 3 collection to avoid the test conflict. Unfortunately, gradle didn't support it by default because gradle will generate temp file with same name during test. So multiple test processes will lead to file access violation. For simple purpose, I created 3 classes and the related test case as following: and the test command is: It will simulate the real project case and provide an easy way to verify quickly if our solution workable or not, 1. Firstly, in order to f...

How to build your own SQLBuilder from scartch

Hibernate is used widely for data access. It is great to release developer from tons of sql scripts. However, the performance is about 50% less than pure jdbc access. For core function, my current project is still using the pure jdbc to access. The pain part is the current code is all write down by stringbuilder which is easy to make a mistake in syntax and missing space between key sql words. My purpose is trying to create simple java class which help build sql prepared statement. The class should be working in the following feature as the first version: 1. Support select, Update, delete sql generation. 2.  Code usage should go with the flow feature 3. Support where, join, and, or key words. 4. support parameters for prepared statement. Let's start from simple simple select/delete statement, the unit test will be as following at first: The implementation will be simple as well: After that, we add support of "WHERE" "UPDATE" as well as al...

The performance of non-blocking jdbc

The JDK 9+ provided incubator to support non-blocking jdbc. The idea is trying to process data when reading or updating the database.  The code support most existing jdbc driver and just need minimal change of incubator code. With the non-blocking jdbc code, the performance increased significantly for updating operations. But just hit slightly change on selection. It make sense since updating will cost on database side and our code will wait longer time to database IO response. The chart clearly show performance comparison between block jdbc and non-block jdbc. Overview, all of them hit the similar query time by access 10000 rows simple data. When using just one thread, the non-block api just took half time of block api to update the database. However, multiple thread increase the performance block api a lot. It should be like it since multiple thread used more system resources to process services. See the table before for detail data: Although multiple thead...

Spring5 + Rest + Agile (5)

Provide Non-blocking REST API: The benefit of non-blocking API will benefit a lot for big scale concurrency calls. We will add @EnableAsync to ResourceServerConfig @Configuration @EnableAsync @EnableResourceServer /*@EnableResourceServer enables a Spring Security filter that authenticates requests using an incoming OAuth2 token.*/ public class ResourceServerConfig extends ResourceServerConfigurerAdapter { and add new async method to demoController: @GetMapping ( "/async-hello" ) public DeferredResult<ResponseEntity<?>> helloAsync () { DeferredResult<ResponseEntity<?>> output = new DeferredResult<>() ; ForkJoinPool. commonPool ().submit(() -> { try { Thread. sleep ( 6000 ) ; } catch (InterruptedException e) { } output .setResult(ResponseEntity. ok ( HELLOWORLD )) ; }) ; return output ; } add refactor test case to support async call with mvcmock @Test public void c...

Spring5 + Rest + Agile (4)

Do more with test: on the previous practice, we run the embed tomcat to test rest, and we don't need do that since spring provide mock mvc to simplify our test work. the older code: /** * The test case used general resttemplate to call api and compare the response. * the whole test is running with an actual tomcat server. */ package org.lz.boilerplate.springrest ; import org.junit.Assert ; import org.junit. Test ; import org.junit.runner. RunWith ; import org.springframework.beans.factory.annotation. Autowired ; import org.springframework.boot.test.context. SpringBootTest ; import org.springframework.boot.test.web.client.TestRestTemplate ; import org.springframework.boot.web.server. LocalServerPort ; import org.springframework.http.* ; import org.springframework.security.oauth2.client.OAuth2RestTemplate ; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails ; import org.springframework.test.context.junit4.SpringRunner ...

Spring5 + Rest + Agile (3)

The basic framework is created already. 1. JWT Auth 2. Hello Rest API. now, it will be good time to switch to database based user authorization. we use customized userDetailService instead of default in memeory user services. Replace InMemeory UserDetailService as DaoUserDetallService @Autowired private UserDetailsService userDetailService ; @Autowired public void globalUserDetails (AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService( userDetailService ) ; } and create new class of it: @Primary @Service public class DaoUserDetailServices implements UserDetailsService { @Autowired private PasswordEncoder bCryptPasswordEncoder ; @Override public UserDetails loadUserByUsername (String name) throws UsernameNotFoundException { if (name.equals( "admin" )) { return new UserPrincipal(name , bCryptPasswordEncoder .encode( "password" ) , "ADMIN" ) ; } else if...