- IoC
- DI
- Beans
- Step1: Creating beans
- @Bean
- @Component
- Step2: Wiring (@Autowiring)
- Step1: Creating beans
- Context
- SpEL
- IoC Container
- @Component
- @Controller
- @Service
- @Repository
- Singleton
- use case:
- immutable beans
- service layers
- repository layers
- points:
- mutable singleton beans + multi thread environment => race condition
- mutable singleton beans + multi thread environment + synchronization => NOT race condition
- NOT best practice = bad practice => mutable singleton beans
- use case:
- Prototype
- Request
- Session
- Application
- WWW
- What -> Aspect
- When -> Advice
- Witch -> Pointcut
- Join Point
- Target Object
- Proxy Object of beans
- Weaving
- intercept
- delegate
- Advice:
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
- Web Server
- Servlet Container (Http web server -> Http servlet object)
- in: ServletRequest
- out: ServletResponse
- Apache Tomcat
- Servlet Container (Http web server -> Http servlet object)
- before:
- /home => HomeServlet
- /about => AboutServlet
- /... => ...Servlet
- after:
- /* => DispatcherServlet
- Approach 1: Spring MVC + Spring Core + Spring Boot + ...
- Approach 2: Spring Core + Spring Boot + ...
- SpringBoot Starters
- spring-boot-starter-web
- Autoconfiguration
- convention-over-configuration
- Actuator and DevTools
- monitor app health, metrics, etc.
- LiveReload Server
- Thymeleaf
- Apache FreeMarker
- jte
- Jakarta Server Page (JSP)
- Jakarta Server Face (JSF)
- ...
- @PathVariable
- www.jimsa.be/app/course <- Path variable
- @RequestParam
- www.jimsa.be/app?course=math&active=true <- Query Param
- Form data
- spring-boot-starter-validation:
- jakarta.validation.constraints.*
- @Digits
- @Max
- @Min
- @Not...
- @Pattern
- @Size
- org.hibernate.validator.constraints.*
- @CreditCardNumber
- @Length
- Currency
- @Range
- @URL
- @UniqueElements
- @EAN
- @ISBN
- jakarta.validation.constraints.*
- Singleton
- Prototype
- Request
- @RequestScope
- Session
- @SessionScope
- Application
- ApplicationScope
- Encoding
- unicode
- base64
- ascii
- file formats
- Encryption
- key
- encryption
- Hashing
- hash value
- hashing function
- Password Encoder (using hash algorithms)
- NoOpPasswordEncoder (No hashing stories in plain text)
- StandardPasswordEncoder
- Pbkdf2PasswordEncoder
- BCryptPasswordEncoder (most commonly use)
- SCryptPasswordEncoder
- H2
- in-memory
- schema.sql
- data.sql
- /h2-console
- sa & ''
- JDBC
- loading driver
- management connections
- statements
- resultSets
- ...
- Spring JDBC
- spring-boot-starter-jdbc
- JdbcTemplate
String lastName = this.jdbcTemplate.queryForObject(
"select last_name from users where id = ?",
String.class,
123L
);
- NamedParameterJdbcTemplate
public int getCount(String firstName) {
String sql = "select count(*) from users where first_name = :first_name";
SqlParameterSource namedParameters = new SqlParameterSource("first_name", firstName);
return this.namedParameterJdbcTemplate.queryForObject(
sql,
namedParameters,
Integer.class
);
}
- Using RowMapper
- BeanPropertyRowMapper
- application.properties
- spring.jdbc.template.*
- spring.jdbc.template.max-rows=500
- Spring Data Projects Link
- Projects:
- Spring Data JDBC
- Spring Data JPA
- Spring Data LDAP
- Spring Data MongoDB
- Spring Data Redis
- Spring Data R2DBC
- Spring Data REST
- Spring Data for Apache Cassandra
- Spring Data for Apache Geode
- Spring Data Couchbase (community module)
- Spring Data Elasticsearch (community module)
- Spring Data Envers
- Spring Data Neo4j (community module)
- ...
- Main modules
- Spring Data Commons
- Repository (marker interface)
- CrudRepository
- ListCrudRepository
- PagingAndSortingRepository
- ListPagingAndSortingRepository
- CrudRepository
- Repository (marker interface)
- Spring Data JPA
- JpaRepository
- Spring Data Commons
- Community modules
- Projects:
create a standalone Spring App which use two databases like MySql and PostgreSQL!
- dependency
- application.yml (application.properties)
- spring.datasource.mysql/postgres.url/username/password/driver-class-name
- jpa.hibernate.ddl-auto
- jpa.mysql/postgres.properties.hibernate.dialect
- DataSource
- EntityManager
- TransactionManager
- LocalContainerEntityManagerFactoryBean
- EntityManagerFactoryBuilder
- PlatformTransactionManager
- JpaTransactionManager
- @Primary
- @Qualifier
- @PersistenceContext(unitName = "mysqlPU")
- private EntityManager mysqlEntityManager;
- @PersistenceContext(unitName = "postgresPU")
- private EntityManager postgresEntityManager;
- JConnector
- JDBC
- JPA
- Spring Data
- Spring Data JPA
- Hibernate
- Query Methods in Spring Data JPA
- introducer + By + criteria
- Auditing Support by Spring Data JPA
- @CreatedDate
- @CreatedBy
- @LastModifiedDate
- @LastModifiedBy
- @interface...
- impl ...
- using ...
import jakarta.persistence.Transient;
@Transient
private String noDbOp; // Won't participate in DB operations like creating a table's column
IMPORTANT : Link
- static
findByOrderByNameDesc()
- dynamic
Sort.by("name").descending().and(Sort.by("age"))
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
Pageable pageable = PageRequest.of(
0,
10,
Sort.by("name").descending()
);
Page<Person> personPage = repo.findByName(name, pageable);
- @Query
- JPQL
- Native SQL query (
nativeQuery=true
)
- @NamedQuery
- @NamedNativeQuery
- Update, Delete, Insert
@Transactional
@Modifying
@RestController = @Controller + @ResponseBody
@RestControllerAdvice
ReponseEntity<T>
RequestEntity<T>
->getBody()
@RequestHeader
@RequestBody
-
protocol
-
domain
-
port
-
@CrossOrigin("*")
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDateTime;
@JsonProperty("first_name")
private String firstName;
@JsonIgnore
private LocalDateTime createdAt;
Requests:
curl --location 'http://localhost:8090/springapp/api/person'
curl --location --request GET 'http://localhost:8090/springapp/api/person/byRequestBodyAnnotation' \
--header 'Content-Type: application/json' \
--data '{
"first_name": "jimsa2",
"last_name": "salehi2"
}'
curl --location 'http://localhost:8090/springapp/api/person' \
--header 'invocationFrom: mobile' \
--header 'Content-Type: application/json' \
--data '{
"first_name": "jimsa3",
"last_name": "salehi3"
}'
curl --location --request DELETE 'http://localhost:8090/springapp/api/person' \
--header 'Content-Type: application/json' \
--data '{
"first_name": "jimsa4",
"last_name": "salehi4"
}'
curl --location --request PATCH 'http://localhost:8090/springapp/api/person' \
--header 'Content-Type: application/json' \
--data '{
"first_name": "jimsa6"
}'
IMPORTANT : Link
- AOP -> MyLogAspect
Libs:
- Java util logging
- Log4J2
- SLF4J
- Logback
- The default logging framework
- The default logging destination is the console
- System.out
- System.err
- Link
Levels:
- fatal
- error
- warn
- info
- debug
- trace
- @Value
- environment.getProperty("...")
-> default into application.properties
- application_prod.properties
- application_dev.properties
spring.profiles.active
- @Profile("!dev")
http://localhost:8090/springapp/actuator/
management.endpoints.web.exposure.include=*
Heap Dumps
- JDK Tools
- jmap
- jcmd
- JVisualVM
- Automatically
java -XX:+HeapDumpOnOutOfMemoryError
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>
- JMX
- JConsole
- Programmatic Way
public static void dumpHeap(String filePath, boolean live) throws IOException {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
mxBean.dumpHeap(filePath, live);
}