java prep - part 3
Published: 2024-06-18 02:42:49

### can we disable the default behaviour of spring explain with example
Yes, in Spring Framework, you can disable or customize default behaviors by overriding configurations or using specific annotations to alter how Spring manages components and processes requests. Let's explore a couple of examples where you might want to disable default behaviors in Spring:

### Example 1: Disabling Default Spring Security Configuration

By default, Spring Security applies a set of security configurations to your application, including basic authentication and authorization rules. You might want to disable these default behaviors if you have custom security requirements.

**Step-by-step Example:**

1. **Disable Security Auto-Configuration**:
   To disable Spring Security's default configuration, you can exclude the `SecurityAutoConfiguration` class from auto-configuration in your main application class or configuration class.

   ```java
   import org.springframework.boot.SpringApplication;
   import org.springframework.boot.autoconfigure.SpringBootApplication;
   import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;

   @SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
   public class MyApplication {

       public static void main(String[] args) {
           SpringApplication.run(MyApplication.class, args);
       }
   }
   ```

   In this example:
   - `@SpringBootApplication` is annotated with `exclude = {SecurityAutoConfiguration.class}`, which disables Spring Security's auto-configuration.

2. **Customize Security Configuration**:
   After disabling default configuration, you can then customize security settings by creating your own `SecurityConfig` class and configuring it based on your specific requirements using `@EnableWebSecurity` and extending `WebSecurityConfigurerAdapter`.

   ```java
   import org.springframework.context.annotation.Configuration;
   import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
   import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

   @Configuration
   @EnableWebSecurity
   public class SecurityConfig extends WebSecurityConfigurerAdapter {

       @Override
       protected void configure(HttpSecurity http) throws Exception {
           // Customize your security configuration here
           http
               .authorizeRequests()
                   .antMatchers("/public/**").permitAll()
                   .anyRequest().authenticated()
                   .and()
               .formLogin()
                   .loginPage("/login")
                   .permitAll()
                   .and()
               .logout()
                   .permitAll();
       }
   }
   ```

   This `SecurityConfig` class provides customized security configurations, overriding the default behavior that was disabled.

### Example 2: Disabling Spring Boot Banner

Spring Boot displays a banner by default during application startup. You may want to disable this banner for specific reasons, such as cleaner log output.

**Step-by-step Example:**

1. **Disable Banner Programmatically**:
   You can disable the banner programmatically by setting `spring.main.banner-mode` property to `OFF` in your `application.properties` or `application.yml`.

   ```properties
   spring.main.banner-mode=OFF
   ```

   This configuration instructs Spring Boot not to display the banner during application startup.

2. **Disable Banner via Configuration Class**:
   Alternatively, you can disable the banner by creating a configuration class and using `SpringApplication.setBannerMode(Banner.Mode.OFF)` in your main application class.

   ```java
   import org.springframework.boot.Banner;
   import org.springframework.boot.SpringApplication;
   import org.springframework.boot.autoconfigure.SpringBootApplication;

   @SpringBootApplication
   public class MyApplication {

       public static void main(String[] args) {
           SpringApplication app = new SpringApplication(MyApplication.class);
           app.setBannerMode(Banner.Mode.OFF);
           app.run(args);
       }
   }
   ```

   Here, `SpringApplication.setBannerMode(Banner.Mode.OFF)` disables the banner explicitly for the `MyApplication`.

### Conclusion:

Spring Framework provides flexibility to disable default behaviors by excluding auto-configurations, overriding configuration classes, or configuring properties. This approach allows developers to customize Spring applications according to specific requirements, ensuring that the framework's default behaviors align with application needs.


### How caching works with example/ archtecture diagram as code


Caching in software systems, including those built with Spring Boot, involves storing frequently accessed data in a faster access storage to improve performance and reduce load on backend systems. 

```java
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value = "usersCache", key = "#userId")
    public User getUserDetails(Long userId) {
        // Simulate fetching user details from a database
        User user = userRepository.findById(userId);
        return user;
    }
}
```

```
# Enable caching
spring.cache.type=ehcache
```

#### with Redis example

```java
import java.io.Serializable;

public class Book implements Serializable {
    private String isbn;
    private String title;
    private String author;

    // Getters and setters (omitted for brevity)

    @Override
    public String toString() {
        return "Book{" +
                "isbn='" + isbn + '\'' +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}
```

```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class BookService {

    private static final String REDIS_KEY = "books";

    @Autowired
    private RedisTemplate<String, Book> redisTemplate;

    public void saveBook(Book book) {
        redisTemplate.opsForHash().put(REDIS_KEY, book.getIsbn(), book);
    }

    public Book getBook(String isbn) {
        return (Book) redisTemplate.opsForHash().get(REDIS_KEY, isbn);
    }

    public void deleteBook(String isbn) {
        redisTemplate.opsForHash().delete(REDIS_KEY, isbn);
    }
}
```