<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Saiteja Erwa on Medium]]></title>
        <description><![CDATA[Stories by Saiteja Erwa on Medium]]></description>
        <link>https://medium.com/@saiteja-erwa?source=rss-3cf75fe15ffc------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*je15EtUiP7UGmbDS7WNDeg.jpeg</url>
            <title>Stories by Saiteja Erwa on Medium</title>
            <link>https://medium.com/@saiteja-erwa?source=rss-3cf75fe15ffc------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 22 May 2026 18:48:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@saiteja-erwa/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Spring Boot: @SpringBootApplication annotation]]></title>
            <link>https://medium.com/@saiteja-erwa/spring-boot-springbootapplication-annotation-805884c2e821?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/805884c2e821</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[spring-boot]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Fri, 14 Jun 2024 11:12:34 GMT</pubDate>
            <atom:updated>2024-06-14T11:12:34.193Z</atom:updated>
            <content:encoded><![CDATA[<p>The @SpringBootAnnotation annotation is equivalent to using @Configuration, @EnableAutoConfiguration, and @ComponentScan with their default attributes.</p><pre>@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan<br>public class Application {<br><br> public static void main(String[] args) {<br>  SpringApplication.run(Application.class, args);<br> }<br><br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Y5wcQHQ4JiN7GZZirbqO0w.png" /><figcaption>@SpringBootApplication</figcaption></figure><h3>@Configuration:</h3><p>Allow to register extra beans in the context or import additional configuration classes.</p><p>This annotation indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.</p><p>There are two modes in @Configuration Full and Lite:</p><h4>Full @Configuration:</h4><p>If a class is annotated with @Configuration then it is considered as a full configuration class. With this, it provides additional features such as “proxying”, which allows for the inter-bean method calls within the same class to be intercepted to ensure that the singleton scope is respected, and the same instance is returned each time.</p><p>@Configuration classes support inter-bean references. This allows the @Bean method to reference another @Bean method in the same configuration class to indicate a dependency.</p><pre>@Configuration<br>public class MediumConfig {<br><br>    @Bean<br>    public MediumA mediumA() {<br>        return new MediumA(mediumB());<br>    }<br><br>    @Bean<br>    public MediumB mediumB() {<br>        return new MediumB();<br>    }<br>}</pre><p>In the example above, the mediumA bean method is called the mediumB bean method to get a reference to the mediumB bean. Because of the proxying in full @Configuration, the mediumB method will not create a new mediumB instance each time it’s called instead, it will return the same instance from the Spring context. Spring will create a CGlib proxy of the class, ensuring that bean methods adhere to the singleton pattern.</p><h4>Lite @Configuration:</h4><p>If a class has methods annotated with @Bean but the class is not annotated with @Configuration, then it is considered a lite configuration. In this case, the bean methods are processed, but the class does not get CGlib-enhanced proxying, which means calling one @Bean method from another @Bean method in the same class will not respect the singleton scope of the beans.</p><p><strong>Importing Configuration:</strong></p><pre>@Configuration<br>@Import({MediumConfig.class, DatabaseConfig.class})<br>public class MainConfig {<br>    // ...<br>}</pre><p>Here MainConfig includes, the beans defined in MediumConfig and DatabaseConfig, this can achieved through the @Import annotation as defined above.</p><p><strong>Profile-specific Configuration:</strong></p><p>@Profile annotation can be used at the class level along with @Configuration or method level along with @Bean, to indicate that they should be loaded only for the particular active profiles.</p><pre>@Configuration<br>@Profile(&quot;dev&quot;) // to load all beans when the spring active profile is dev<br>public class DataSourceConfig {<br><br>// ...    <br><br>}</pre><pre>@Configuration<br>public class DataSourceConfig {<br><br>  @Bean<br>  @Profile(&quot;prod&quot;) // to load only when the spring active profile is prod<br>  public DataSourceMySql dataSource() {<br>      return new DataSourceMySql();<br>  }<br>}</pre><h3>@EnableAutoConfiguration:</h3><p>It enables the auto-configuration of the spring application based on the dependencies present in the classpath.</p><p>When Spring Boot&#39;s main class is annotated with @EnableAutoConfiguration or @SpringBootApplication, we are instructing Spring Boot to automatically configure the application based on jars present in the classpath like data sources, JPA repositories, Spring MVC and more.</p><p><strong>Internal Working:</strong></p><p>Spring Boot auto-configuration attempts to intelligently configure beans as per the requirements. It does this by scanning the classpath for specific classes that, if present, trigger the auto-configuration of certain features.</p><p>To see the internal working of the auto-configuration of spring boot, run the application in debug mode this can be done by setting the debug=true in the applcation.properties file. The logs can be seen below.</p><pre>Positive matches:<br>-----------------<br><br>   AopAutoConfiguration matched:<br>      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)<br><br>   AopAutoConfiguration.AspectJAutoProxyingConfiguration matched:<br>      - @ConditionalOnClass found required class &#39;org.aspectj.weaver.Advice&#39; (OnClassCondition)<br><br>   DataSourceAutoConfiguration.PooledDataSourceConfiguration matched:<br>      - AnyNestedCondition 1 matched 1 did not; NestedCondition on DataSourceAutoConfiguration.PooledDataSourceCondition.PooledDataSourceAvailable PooledDataSource found supported DataSource; NestedCondition on DataSourceAutoConfiguration.PooledDataSourceCondition.ExplicitType @ConditionalOnProperty (spring.datasource.type) did not find property &#39;type&#39; (DataSourceAutoConfiguration.PooledDataSourceCondition)<br>      - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) did not find any beans (OnBeanCondition)<br><br>   DataSourceAutoConfiguration.PooledDataSourceConfiguration#jdbcConnectionDetails matched:<br>      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; SearchStrategy: all) did not find any beans (OnBeanCondition)<br>  <br>   // some auto-configuration classes<br><br>Negative matches:<br>-----------------<br><br>   ActiveMQAutoConfiguration:<br>      Did not match:<br>         - @ConditionalOnClass did not find required class &#39;jakarta.jms.ConnectionFactory&#39; (OnClassCondition)<br><br>   AopAutoConfiguration.AspectJAutoProxyingConfiguration.JdkDynamicAutoProxyConfiguration:<br>      Did not match:<br>         - @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property &#39;proxy-target-class&#39; (OnPropertyCondition)<br><br>  // Other logs</pre><p><strong>Positive matches:</strong> Under this, you can find all the matched auto-configuration classes as per the jars present in the classpath.</p><p>Based on the starter dependencies or by default it will add the jars to the classpath, and then spring boot is intelligent enough to scan and load the beans as required.</p><p>For example, consider DataSourceAutoConfiguration class. There is a <em>@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})</em><br>if the DataSource, and EmbeddedDatabaseType classes are available in the classpath then only auto-configure the default DataSource.</p><pre>@AutoConfiguration(<br>    before = {SqlInitializationAutoConfiguration.class}<br>)<br>@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})<br>@ConditionalOnMissingBean(<br>    type = {&quot;io.r2dbc.spi.ConnectionFactory&quot;}<br>)<br>@EnableConfigurationProperties({DataSourceProperties.class})<br>@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceCheckpointRestoreConfiguration.class})<br>public class DataSourceAutoConfiguration {<br>//....<br>}</pre><p>Then how does it automatically connect to the DB ? <br>It does by <em>@EnableConfigurationProperties({DataSourceProperties.class})</em><br>If we observe the DataSourceProperties class, it is reading properties using the prefix “spring.datasource” the driverClassName, url, username etc., defined in the application properties or yml file.</p><pre>@ConfigurationProperties(<br>    prefix = &quot;spring.datasource&quot;<br>)<br>public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {<br>    private ClassLoader classLoader;<br>    private boolean generateUniqueName = true;<br>    private String name;<br>    private Class&lt;? extends DataSource&gt; type;<br>    private String driverClassName;<br>    private String url;<br>    private String username;<br>    private String password;<br>    private String jndiName;<br>    // ...<br>}</pre><p>Like this, you can refer to other auto-configuration classes for understanding.</p><p><strong>Negative Matches: </strong>Under this, you can find all classes that are marked as, not eligible for the auto-configuration. Like ActiveMQAutoConfiguration, as did not find the required class.</p><p><strong>Customizing Auto-configuration:</strong></p><ul><li><strong>Excluding Specific Configurations:<br></strong>You can exclude certain auto-configuration classes that you don’t want to apply using the exclude attribute of @EnableAutoConfiguration:</li></ul><pre>@SpringBootApplication<br>@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})<br>public class Application {<br> public static void main(String[] args) {<br>  SpringApplication.run(Application.class, args);<br> }<br>}</pre><p>Or by using the spring.autoconfigure.exclude property in your application.properties or application.yml.</p><pre>spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration</pre><ul><li><strong>Overriding Auto-configured Beans:<br></strong>You can define your configurations to override the defaults provided by auto-configuration. For example, if you declare your own DataSource bean, Spring Boot will override this with the default one.</li></ul><pre>@Configuration<br>public class DataSourceConfig {<br><br>  @Bean<br>  @Profile(&quot;!dev&quot; &amp; &quot;!test&quot;) // to load bean other than dev and test active profile<br>  public DataSource dataSource() {<br>  //get the properties from properties.<br>  // password from the secrets vault<br>  // and create DataSource<br>  return DataSource();<br>  }<br><br>}</pre><h3>@ComponentScan:</h3><p>This is used to specify the packages that the spring framework should scan for the components, services, repositories, and configurations. It enables the detection of components(@Component), repositories(@Repository), services(@Service), and controllers(@Controller) that are annotated as such so that they can be registered as beans in the Spring application context.</p><p>By default, Spring Boot scans all the classes that are under the main class where @SpringBootApplication is annotated. Which defaults to scanning the package of the main class and all its sub-packages.</p><p>If you want to override the default component scan settings of @SpringBootApplication, you can add @ComponentScan with your custom configuration to your main application class.</p><pre>@SpringBootApplication<br>@ComponentScan(basePackages = &quot;com.example.medium&quot;)<br>public class MainClass {<br>  //...<br>}</pre><p>When you have components in packages that are not sub-packages of your main configuration class, need to explicitly configure @ComponentScan to include those packages.</p><pre>@Configuration<br>@ComponentScan(basePackages = &quot;com.project.medium&quot;)<br>public class SubConfiguration {<br>  //...<br>}</pre><p><strong>Attributes of @ComponentScan:</strong></p><ul><li>basePackages and basePackageClasses:<br>These attributes are used to specify the packages to scan explicitly. If you prefer type-safety over string literals, you can use basePackageClasses.</li></ul><pre>//Here in this case. Spring Boot will scan the packages of the classes provided.<br>@ComponentScan(basePackageClasses = { MediumService.class, MediumRepository.class })<br><br>// Spring Boot will scan the packages provided as String literals<br>@ComponentScan(basePackages = &quot;com.example.medium&quot;)</pre><ul><li><strong>includeFilters and excludeFilters:<br></strong>These attributes are used to include or exclude specific components from being scanned.</li></ul><pre>//Includes only components that are annotated with @Service, as defined FilterType.ANNOTATION<br>//and excludes components that are annotated with @Configuration as defined FilterType.ANNOTATION<br>@ComponentScan(<br>    basePackages = &quot;com.example.medium&quot;,<br>    includeFilters = @Filter(type = FilterType.ANNOTATION, classes = Service.class),<br>    excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)<br>)</pre><ul><li><strong>lazyInit:<br></strong>This attribute is used whether or not the beans should be initialized lazily.</li></ul><pre>@ComponentScan(lazyInit = true)</pre><h4>Conclusion:</h4><ul><li>@Configuration: This annotation is a key element in defining application context configuration in a Spring or Spring Boot application. It provides a declarative approach to define beans and dependencies and supports inter-bean references, profile-specific and conditional configuration.</li><li>@EnableAutoConfiguration: This annotation is a powerful feature in Spring Boot that helps developers set up and run the application with minimal configuration. It works by conditionally configuring beans based on the application’s classpath and the context environment.</li><li>@ComponentScan: This annotation controls the detection and registering of the beans in the Spring application context of the application components. It provides the attributes and capabilities allowing us to structure your application correctly and maintain control over your application context.</li></ul><p>Understanding how to use @Configuration, @EnableAutoConfiguration, and @ComponentScan effectively is essential for designing well-structured and maintainable Spring applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=805884c2e821" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: DTO validation — Using Groups and Payload attributes]]></title>
            <link>https://medium.com/@saiteja-erwa/spring-boot-dto-validation-using-groups-and-payload-attributes-e2c139f5b1ef?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/e2c139f5b1ef</guid>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Mon, 10 Jun 2024 16:32:50 GMT</pubDate>
            <atom:updated>2024-06-10T16:32:50.440Z</atom:updated>
            <content:encoded><![CDATA[<h3>Spring Boot: DTO validation — Using Groups and Payload attributes</h3><p>In Spring Boot, Data Transfer Object(DTO) validation is commonly done using the Bean Validation API (JSR 380). When annotating DTO fields with validation constraints like (@NotNull, @Size etc. ), the <em>groups</em> and <em>payload</em> attributes provide additional control over the validation process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/591/1*ChNOA_6RlhXZ0GKUbtaEyA.png" /></figure><h4><strong>Groups:</strong></h4><p>The <em>groups</em> attribute allows you to categorize constraints into validation groups. This is useful when you want different validation rules to apply in different conditions.</p><p>For example, we might require certain validation constraints that should be applied only when creating the new object, and other validation constraints should be applied only when updating the object.</p><p>Define the validation groups as interfaces.</p><pre>public interface createMedium{<br>// can be empty interface<br>}<br><br>public interface updateMedium{<br>// can be empty interface<br>}</pre><p>In the DTO class use the above validation groups.</p><pre>public class MediumDTO {<br>    @NotNull(groups = createMedium.class)<br>    @Size(min = 5, max = 20, groups = createMedium.class)<br>    private String username;<br><br>    @NotNull(groups = updateMedium.class)<br>    private String password;<br>    <br>    //setters and getters<br>}</pre><p>When validating the MediumDTO, we can specify which group should be validated.</p><pre>public void validate() {<br>  MediumDTO mediumDto = new MediumDTO();<br>  // ... populate mediumDto fields ...<br>  mediumDto.setUserName(&quot;medium&quot;);<br>  mediumDto.setPassword(&quot;********&quot;);<br>  <br>  Validator validator = Validation.buildDefaultValidatorFactory().getValidator();<br>  Set&lt;ConstraintViolation&lt;MediumDTO&gt;&gt; violations = validator.validate(mediumDto, CreateMedium.class);<br>  //Here it ensures that only the constraints associated with the CreateMedium group are validated.<br>  //In this example it is @NotNull, @Size constraints on username field are validated.<br><br>  //If it has a violation then throw the error<br>  if (violations != null &amp;&amp; !violations.isEmpty()) {<br>    String error = violations.stream()<br>                    .map(violation -&gt; violation.getPropertyPath()+&quot; &quot;+violation.getMessage())<br>                    .collect(Collectors.toList()).toString();<br>    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, error);<br>  }<br>}<br></pre><p><strong>Benefits of Using Groups</strong></p><p>• Contextual Validation: Groups enable you to validate the same DTO differently based on the operation being performed (e.g., create vs. update).</p><p>• Performance: They can improve performance by avoiding unnecessary validations that are not relevant to the current context.</p><p>• Modularity: Groups help to keep the validation rules modular and organized by context.</p><p>• Flexibility: They provide flexibility to apply different validation rules without the need to create separate DTOs for each context.</p><p><strong>Conclusion</strong></p><p>The use of validation groups in Spring Boot is a powerful feature for managing complex validation logic. It allows you to annotate a single DTO with different validation rules and selectively apply those rules based on the operation being performed, leading to cleaner, more maintainable code.</p><h4>Payload:</h4><p>The <em>payload</em> attribute is used to provide additional metadata or context about the validation constraint that can be used when a constraint violation occurs.</p><p>Payloads are defined as classes that implement the javax.validation.Payload interface.</p><pre>public interface SeverityLevel {<br>    //can be empty<br>    interface Info extends Payload {}<br>    interface Warn extends Payload {}<br>    interface Error extends Payload {}<br>}</pre><p>In the DTO class use the above payload interfaces.</p><p>Different payloads are associated with different validation constraints. If any constraint is violated, the payload associated with that constraint will be included in the constraint violation information.</p><pre>public class MediumDto {<br><br>    @NotBlank(message = &quot;Username is required&quot;, payload = SeverityLevel.Error.class)<br>    private String username;<br><br>    @Email(message = &quot;Email must be valid&quot;, payload = SeverityLevel.Warn.class)<br>    private String email;<br><br>    @Size(min = 8, message = &quot;Password must be at least 8 characters&quot;, payload = SeverityLevel.Info.class)<br>    private String password;<br>}</pre><p>When a constraint violation occurs, the payloads can be inspected to determine the severity or type of the violation. This can be useful when you want to handle violations differently based on their payload.</p><pre>public void validate() {<br>  MediumDTO mediumDto = new MediumDTO();<br>  // ... populate mediumDto fields ...<br>  Validator validator = Validation.buildDefaultValidatorFactory().getValidator();<br>  Set&lt;ConstraintViolation&lt;MediumDTO&gt;&gt; violations = validator.validate(mediumDto);<br> <br>  for (ConstraintViolation&lt;UserDto&gt; violation : violations) {<br>    Payload payload = violation.getConstraintDescriptor().getPayload().iterator().next();<br><br>    if (payload instanceof SeverityLevel.Error) {<br>        // Handle error-level violation<br>    } else if (payload instanceof SeverityLevel.Warn) {<br>        // Handle warning-level violation<br>    } else if (payload instanceof SeverityLevel.Info) {<br>        // Handle info-level violation<br>    }<br>}<br>}</pre><p><strong>Benefits of Using Payloads</strong></p><p>• Metadata: Payloads provide a way to attach additional information or metadata to a constraint violation.</p><p>• Custom Handling: They allow for custom handling of constraint violations based on the payload information, such as logging different severity levels differently or presenting the user with different messages.</p><p>• Flexibility: Payloads offer flexibility in how you report and handle validation errors, making it possible to integrate with various error reporting or user notification systems.</p><p><strong>Limitations and Considerations</strong></p><p>While payloads provide useful context, they are not often used for carrying complex data because:</p><p><strong>• </strong>They require casting from the Payload type to the specific payload interface.</p><p><strong>• </strong>They are not intended for passing stateful information or complex data structures.</p><p><strong>Conclusion</strong></p><p>The payload attribute in DTO validation is a mechanism that allows developers to attach additional metadata to validation constraints. This can be particularly useful for differentiating the severity of constraint violations, customizing error handling with more meaningful messages, or integrating with other systems that might need to interpret the validation results differently based on the payload information. Although not required for simple validation cases, payloads can be an important tool in complex applications with advanced validation needs.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e2c139f5b1ef" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: Custom Validation Annotation — ConstraintValidator]]></title>
            <link>https://medium.com/@saiteja-erwa/springboot-custom-validation-annotation-constraintvalidator-d06569d43695?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/d06569d43695</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Fri, 07 Jun 2024 15:21:58 GMT</pubDate>
            <atom:updated>2024-06-07T15:26:18.233Z</atom:updated>
            <content:encoded><![CDATA[<h3>Spring Boot: Custom Validation Annotation — ConstraintValidator</h3><p>Besides predefined validators, when we need to validate a more particular type of input, we can create our custom validation logic.</p><p>This can be achieved by combining the custom annotation with a corresponding <em>ConstraintValidator</em> implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/591/1*SWCnDQ2XQRACVkouGb45gQ.png" /></figure><h4>Steps to create custom validation annotation:</h4><ul><li><strong>Create a custom annotation:</strong> Create an annotation and mark it with the @Constraint annotation, pointing to your <em>ConstraintValidator</em> implementation. Add any parameters you need in the custom annotation as annotation attributes.</li></ul><pre>@Documented<br>@Constraint(validatedBy = NumberValidator.class)<br>@Target({ ElementType.METHOD, ElementType.FIELD })<br>@Retention(RetentionPolicy.RUNTIME)<br>public @interface Number {<br><br>    int value() default 200; // The default length<br> <br>    boolean isEmptyAllowed() default false; // Default to false<br><br>    String message() default &quot;Number must be positive&quot;; // Default error message<br><br>    Class&lt;?&gt;[] groups() default {}; // Required for validation constraints<br><br>    Class&lt;? extends Payload&gt;[] payload() default {}; // Required for validation constraints<br>}</pre><ul><li><strong>Implement the ConstraintValidator Interface: </strong>Create a class that implements the ConstraintValidator interface. This interface defines two methods: <em>initialize</em> (to initialize the validator) and <em>isValid</em> (to perform the validation logic).</li></ul><pre>public class NumberValidator implements ConstraintValidator&lt;Number, String&gt; {<br><br>    private static final Pattern CHECK = Pattern.compile(&quot;^[0-9]*$&quot;);<br><br>    private int number;<br><br>    private boolean isEmptyAllowed;<br><br>    @Override<br>    public void initialize(Number constraintAnnotation) {<br>        this.number = constraintAnnotation.value();<br>        this.isEmptyAllowed = constraintAnnotation.isEmptyAllowed();<br>    }<br><br>    @Override<br>    public boolean isValid(String value, ConstraintValidatorContext context) {<br>        if (StringUtils.isBlank(value)) {<br>          // ByDefault set to false in the custom annotation. <br>          // or else get from the parameter defined in the annotation ex. @Number(length = 4, isEmptyAllowed = false; message = &quot;Extension should not be greater than 4&quot;)<br>          // Got this value from the above initialize method (constraintAnnotation.isEmptyAllowed())<br>          return isEmptyAllowed;<br>        }<br>        // ByDefault set to 200 in the custom annotation.<br>        // or else get from the parameter defined in the annotation ex. @Number(length = 4, isEmptyAllowed = false; message = &quot;Extension should not be greater than 4&quot;)<br>        // Got this value from the above initialize method (constraintAnnotation.value())<br>        // And check the given value matches the pattern.<br>        // If both condition satisfies return true<br>        return value.trim().length() &lt;= length &amp;&amp; CHECK.matcher(value).matches();<br>    }<br>}</pre><ul><li><strong>Use the Custom Annotation: </strong>After defining the custom annotation and its validator, use the annotation on fields.</li></ul><pre>public class PhoneExtensionDTO {<br><br>  // Here we are overriding the default properties of custom annotation <br>  // of length, isEmptyAllowed, message<br>  @Number(length = 4, isEmptyAllowed = false; message = &quot;Extension should not be greater than 4&quot;)<br>  private String extension;<br>}</pre><p>When validating an instance of PhoneExtensionDTO, Spring’s validation mechanism will ensure that the extension field is not greater than 4 characters long, as specified by the @Number annotation.</p><p>To enable the validation, make sure that the @Valid annotation is used in the appropriate places, such as controller method parameters:</p><pre>@RestController<br>public class MediumController {<br><br>    @PostMapping(&quot;/validate&quot;)<br>    public String validateExtension(@RequestBody @Valid PhoneExtensionDTO extension) {<br>        return &quot;Validation passed!&quot;;<br>    }<br><br>}</pre><p>The above code will result in validation being performed when a POST request is made to /validate, and if the extension does not meet the criteria, a validation error will be thrown.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d06569d43695" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: Bean Life Cycle — Customizing the Nature of a Bean]]></title>
            <link>https://medium.com/@saiteja-erwa/springboot-customizing-the-nature-of-a-bean-79562d582b33?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/79562d582b33</guid>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Sat, 01 Jun 2024 17:48:16 GMT</pubDate>
            <atom:updated>2024-06-07T15:32:55.552Z</atom:updated>
            <content:encoded><![CDATA[<ol><li>Lifecycle Callbacks.</li><li>ApplicationContextAware and BeanNameAware.</li><li>Other Aware Interfaces.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*x_Tx_ayEFeTKF_9IWs-oWA.png" /><figcaption>Spring Bean LifeCycle</figcaption></figure><h4>Lifecycle Callbacks:</h4><p>To interact with the container’s management of the bean lifecycle, you can implement the Spring “InitializingBean” and “DisposableBean” interfaces. The container calls afterPropertiesSet() and destroy() respectively perform certain actions upon initialization and destruction of your beans.</p><p>The JSR-250 “@PostContruct” and “@PreDestroy” annotations are generally considered best practices for receiving lifecycle callbacks in a modern Spring application. Using these annotations means that your beans are not coupled to Spring-specific interfaces. For details, <a href="https://medium.com/@saiteja-erwa/spring-boot-postconstruct-and-predestroy-69f364d9124a">https://medium.com/@saiteja-erwa/spring-boot-postconstruct-and-predestroy-69f364d9124a</a></p><p>Internally, the Spring Framework uses BeanPostProcessor implementations to process any callback interfaces it can find and call the appropriate methods. If you need custom features or other lifecycle behaviour Spring does not by default offer, you can implement a BeanPostProcessor yourself.</p><h4>- Initialization Callbacks</h4><p>The “org.springframework.beans.factory.InitializingBean” interface lets a bean perform initialization work after the container has set all necessary properties on the bean. The InitializingBean interface specifies a single method.</p><pre>void afterPropertiesSet() throws Exception;</pre><pre>public class OrderBean implements InitializingBean {<br><br> @Override<br> public void afterPropertiesSet() {<br>  //Do some initialization work<br> }<br>}</pre><p>In the case of XML-based configuration metadata, you can use the “init-method” attribute to specify the name of the method that has a void no-argument signature.</p><pre>&lt;bean id=&quot;orderInitBean&quot; class=&quot;examples.OrderBean&quot; init-method=&quot;init&quot;/&gt;</pre><pre>public class SampleBean {<br><br> public void init() {<br>  //Do some initialization work<br> }<br>}</pre><h4>- Destruction Callbacks</h4><p>Implementing the “org.springframework.beans.factory.DisposableBean” interface lets a bean get a callback when the container that contains it is destroyed. The DisposableBean interface specifies a single method.</p><pre>void destroy() throws Exception;</pre><pre>public class OrderBean implements DisposableBean {<br><br> @Override<br> public void destroy() {<br>  // Do some destruction work (like releasing pooled connections)<br> }<br>}</pre><p>With XML-based configuration metadata, you can use the “destroy-method” attribute on the &lt;bean/&gt;</p><pre>&lt;bean id=&quot;orderDestructionBean&quot; class=&quot;examples.OrderBean&quot; destroy-method=&quot;cleanup&quot;/&gt;</pre><pre>public class OrderBean {<br><br> public void cleanup() {<br>  // Do some destruction work (like releasing pooled connections)<br> }<br>}</pre><h4>Combining Lifecycle Mechanisms</h4><p>As of Spring 2.5, you have three options for controlling bean lifecycle behavior:</p><ul><li>The <em>InitializingBean</em> and <em>DisposableBean</em> callback interfaces</li><li>Custom <em>init()</em> and <em>destroy()</em> methods</li><li>The <em>@PostContruct</em> and <em>@PreDestroy</em> annotations</li></ul><p>Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:</p><ol><li>Methods annotated with <em>@PostContruct</em></li><li>afterPropertiesSet() as defined by the <em>InitializingBean </em>callback interface</li><li>A custom-configured init() method</li></ol><p>Destroy methods are called in the same order:</p><ol><li>Methods annotated with <em>@PreDestroy</em></li><li>destroy() as defined by the <em>DisposableBean</em> callback interface</li><li>A custom-configured destroy() method</li></ol><h4>Startup and Shutdown Callbacks:</h4><p>The Lifecycle interface defines the essential methods for any object that has its lifecycle requirements (such as starting and stopping some background process):</p><pre>public interface Lifecycle {<br><br> void start();// This method is called when the application context is started or refreshed. Beans that implement this method can perform any necessary tasks to start up, such as allocating resources or starting background threads<br><br> void stop(); // This method is called when the application context is being closed, allowing beans to release any resources or perform other cleanup before the application is shut down.<br><br> boolean isRunning(); // Which should return true if the component is currently running or false if it is not running<br>}</pre><p>Any Spring-managed object may implement the Lifecycle interface. Then, when the ApplicationContext itself receives start and stop signals (for example, for a stop/restart scenario at runtime), it cascades those calls to all Lifecycle implementations defined within that context.</p><p>It does this by delegating to a LifecycleProcessor, as shown below:</p><pre>public class LifecycleProcessor implements Lifecycle {<br><br>    private volatile boolean running = false;<br><br>    @Override<br>    public void start() {<br>        // Start the component.<br>        running = true;<br>        System.out.println(&quot;LifecycleBean has started.&quot;);<br>        // Perform startup logic here (e.g., start a background thread)<br>    }<br><br>    @Override<br>    public void stop() {<br>        // Stop the component.<br>        running = false;<br>        System.out.println(&quot;LifecycleBean has stopped.&quot;);<br>        // Perform shutdown logic here (e.g., stop a background thread)<br>    }<br><br>    @Override<br>    public boolean isRunning() {<br>        // Check if the component is currently running.<br>        return running;<br>    }<br>}</pre><p>Once you define a bean that implements the Lifecycle interface, you can register it in the Spring application context (either through XML configuration, Java configuration, or component scanning), and the container will automatically call the start() and stop() methods at the appropriate times in the application’s lifecycle.</p><p>With Java configuration, you can use Java classes annotated with @Configuration to define your beans. Here’s an example of a Java config class that registers a Lifecycle bean:</p><pre>@Configuration<br>public class AppConfig {<br><br>    @Bean<br>    public LifecycleProcessor myLifecycleBean() {<br>        return new LifecycleProcessor();<br>    }<br>}</pre><p>Spring also provides a more specific SmartLifecycle interface, which extends the Lifecycle and adds more control over the startup and shutdown phases</p><p><em>Shutdown Callbacks:</em></p><p>This section applies only to non-web applications. Spring’s web-based ApplicationContext implementations already have code in place to gracefully shut down the Spring IoC container when the relevant web application is shut down.</p><h4><strong>ApplicationContextAware and BeanNameAware:</strong></h4><p>When an ApplicationContext creates an object instance that implements the org.springframework.context.ApplicationContextAware interface, the instance is provided with a reference to that ApplicationContext.</p><pre>public interface ApplicationContextAware {<br><br> void setApplicationContext(ApplicationContext applicationContext) throws BeansException;<br>}<br></pre><p>The ApplicationContextAware interface is used when a bean needs access to the Spring ApplicationContext that it is defined in. For example, a bean might need to look up other beans, access resources, or query the environment settings.</p><pre>@Component<br>public class AwareBean implements ApplicationContextAware {<br><br>    private ApplicationContext applicationContext;<br><br>    @Override<br>    public void setApplicationContext(ApplicationContext applicationContext) {<br>        this.applicationContext = applicationContext;<br>        // Use the application context as needed<br>    }<br><br>    // ...<br>}</pre><p>The BeanNameAware interface is used by beans that want to know what their bean name is within the Spring container. This can be useful for beans that need to interact with the container more dynamically or when they need to relate their bean name to other operations within the application.</p><pre>public interface BeanNameAware {<br><br> void setBeanName(String name) throws BeansException;<br>}</pre><pre>@Component<br>public class MyBeanName implements BeanNameAware {<br><br>    private String beanName;<br><br>    @Override<br>    public void setBeanName(String name) {<br>        this.beanName = name;<br>        // You now know the bean&#39;s name within the container<br>    }<br><br>    // Other methods...<br>}</pre><p>Invoked after the population of normal bean properties but before an init callback such as InitializingBean.afterPropertiesSet() or a custom init-method.</p><p><strong>Notes:</strong></p><ul><li>These interfaces are typically used by infrastructure beans or beans that provide framework-level functionality.</li><li>It’s important to note that when using ApplicationContextAware it can lead to tightly coupling the code to Spring. As a best practice, consider using dependency injection if it is required instead of directly accessing the ApplicationContext.</li><li>Beans that implement ApplicationContextAware and BeanNameAware must be Spring-managed beans to receive the callbacks correctly. They won’t work on POJOs that are not created by the Spring container.</li><li>Other AwareInterfaces include <em>MessageSourceAware</em>, <em>ResourceLoaderAware</em>, and <em>EnvironmentAware</em>, each allowing access to various parts of the Spring framework’s functionality.</li></ul><h4>BeanPostProcessor:</h4><p>Factory hook that allows for custom modification of new bean instances. For example, checking for marker interfaces or wrapping beans with proxies.</p><p>An ApplicationContext can autodetect BeanPostProcessor beans in its bean definitions and apply those post-processors to any beans subsequently created.</p><p>A plain BeanFactory allows for programmatic registration of post-processors, applying them to all beans created through the bean factory.</p><p>The BeanPostProcessor interface defines two callback methods that the Spring IoC container calls for each bean instance:</p><ol><li>postProcessBeforeInitialization(Object bean, String beanName) : Apply this BeanPostProcessor to the given new bean instance <em>before</em> any bean initialization callbacks (like InitializingBean’s afterPropertiesSet() or a custom init-method).</li><li>postProcessAfterInitialization(Object bean, String beanName) : Apply this BeanPostProcessor to the given new bean instance <em>after</em> any bean initialization callbacks (like InitializingBean’s afterPropertiesSet or a custom init-method).</li></ol><p>Example to implement custom BeanPostProcessor:</p><pre>@Component<br>public class MediumBeanPostProcessor implements BeanPostProcessor {<br><br>    @Override<br>    public Object postProcessBeforeInitialization(Object bean, String beanName) {<br>        // This method can be used to perform some operations before the initialization<br>        // of the bean.<br>        System.out.println(&quot;Before initialization: &quot; + beanName);<br>        return bean; // You can return any object, even a proxy around the bean.<br>    }<br><br>    @Override<br>    public Object postProcessAfterInitialization(Object bean, String beanName) {<br>        // This method can be used to perform operations after the initialization of the bean.<br>        // For instance, wrapping the bean with a proxy if necessary.<br>        System.out.println(&quot;After initialization: &quot; + beanName);<br>        return bean; // You can return any object, even a proxy around the bean.<br>    }<br>}</pre><p><strong>Notes:</strong></p><ul><li>It’s important to use this feature judiciously since it can impact the performance of your application if overused or used improperly.</li><li>Since BeanPostProcessor itself is a bean, it follows the standard bean lifecycle and will go through its postProcessBeforeInitialization() and postProcessAfterInitialization() methods, so you need to be careful to avoid potential recursion issues if a BeanPostProcessor is processing itself.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=79562d582b33" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: BeanFactory and ApplicationContext]]></title>
            <link>https://medium.com/@saiteja-erwa/spring-boot-beanfactory-and-applicationscontext-314a4889b132?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/314a4889b132</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Fri, 24 May 2024 06:43:19 GMT</pubDate>
            <atom:updated>2024-05-24T12:36:40.856Z</atom:updated>
            <content:encoded><![CDATA[<p>The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container.</p><p>The <a href="https://docs.spring.io/spring-framework/docs/6.1.7/javadoc-api/org/springframework/beans/factory/BeanFactory.html">BeanFactory</a> interface provides an advanced configuration mechanism capable of managing any type of object. The BeanFactory provides the configuration framework and basic functionality.</p><p>The <a href="https://docs.spring.io/spring-framework/docs/6.1.7/javadoc-api/org/springframework/context/ApplicationContext.html">ApplicationContext</a> adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*-YJg_Ppf8Fc3uDThMW8G-w.png" /><figcaption>Hierarchy</figcaption></figure><p>Users are sometimes unsure whether a BeanFactory or an ApplicationContext are best suited for use in a particular situation. Normally when building most applications in a J2EE environment, the best option is to use the ApplicationContext, since it offers all the features of the BeanFactory and adds on to it in terms of features, while also allowing a more declarative approach to the use of some functionality, which is generally desirable. The main usage scenario when you might prefer to use the BeanFactory is when memory usage is the greatest concern (such as in an applet where every last kilobyte counts), and you don’t need all the features of the ApplicationContext.</p><h4><strong>BeanFactory:</strong></h4><ul><li>The BeanFactory is the actual container that instantiates, configures, and manages several beans.</li><li>The most commonly used simple BeanFactory implementation is org.springframework.beans.factory.xml.XmlBeanFactory</li><li>The BeanFactory does have to be instantiated somehow. This can happen via explicit user code such as:</li></ul><pre>Resource res = new FileSystemResource(&quot;beans.xml&quot;);<br>XmlBeanFactory factory = new XmlBeanFactory(res);<br>or<br><br>Resource res = new ClassPathResource(&quot;beans.xml&quot;);<br>BeanFactory factory = new XmlBeanFactory(res);</pre><ul><li>BeanFactory loads beans on demand. The beans defined in our <em>BeanFactory</em> will be loaded only when we explicitly call the <em>getBean()</em> method<em>.</em></li></ul><pre>Resource res = new ClassPathResource(&quot;beans.xml&quot;);<br>BeanFactory factory = new XmlBeanFactory(res);<br>Medium medium = (Student) factory.getBean(&quot;medium&quot;);</pre><h4>ApplicationContext:</h4><ul><li>While the beans package provides basic functionality for managing and manipulating beans, often programmatically, the context package adds ApplicationContext, which enhances BeanFactory functionality in a more <em>framework-oriented style</em>.</li></ul><ol><li><em>MessageSource</em>, providing access to messages in, i18n-style.</li><li><em>Access to resources</em>, such as URLs and files.</li><li><em>Event propagation</em> to beans implementing the ApplicationListener interface.</li><li><em>Loading of multiple (hierarchical) contexts</em>, allowing each to be focused on one particular layer, for example, the web layer of an application.</li></ol><ul><li>There are so many implementation classes that can be used such as <strong>ClassPathXmlApplicationContext</strong>, <strong>FileSystemXmlApplicationContext</strong>, <strong>AnnotationConfigWebApplicationContext</strong> etc.</li></ul><pre>public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,<br>  MessageSource, ApplicationEventPublisher, ResourcePatternResolver {<br>  ....<br>}</pre><h4>Internationalization using MessageSource:</h4><p>The <em>ApplicationContext</em> interface extends an interface called <em>MessageSource</em> and, therefore, provides internationalization (“i18n”) functionality. Spring provides three MessageSource implementations, <em>ResourceBundleMessageSource, ReloadableResourceBundleMessageSource </em>and<em> StaticMessageSource.</em></p><ol><li>Create the <em>messages.properties</em> file on the classpath:</li><li>Create a configuration class with bean definition.</li><li>Inject MessageSource in OrderService, and use the messageSource to read the message.</li></ol><pre>order.name=MobilePhone Order</pre><pre>@Configuration<br>public class OrderConfig {<br><br>  @Bean<br>  public MessageSource messageSource() {<br>    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();<br>    messageSource.setBasename(&quot;config/messages&quot;);//{path}/{filename}<br>    return messageSource;<br>  }<br><br>}</pre><pre>@Service<br>public class OrderService {<br><br>  @Autowired<br>  public MessageSource messagSource;<br><br>  ....<br>  ..<br><br>  public getOrderMessage() {<br>    messageSource.getMessage(&quot;order.name&quot;, null, Locale.ENGLISH);<br>  }<br>}</pre><p>When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name messageSource. If such a bean is found, all calls to the preceding methods are delegated to the message source.</p><h4>Event Handling:</h4><p>Event handling in the ApplicationContext is provided through the <strong><em>ApplicationEvent</em></strong> class and <strong><em>ApplicationListener</em></strong> interface.</p><p>If a bean that implements the ApplicationListener interface is deployed into the context, every time an ApplicationEvent gets published to the ApplicationContext, that bean will be notified. Essentially, this is the standard <em>Observer</em> design pattern.</p><p><strong>Spring provides three standard events:</strong></p><p><em>ContextRefreshedEvent:</em> Event published when the ApplicationContext is initialized or refreshed. Initialized here means that all beans are loaded, singletons are pre-instantiated and the ApplicationContext is ready for use.</p><pre>@Component<br>public class AppEvents {<br><br>  @EventListener(ContextClosedEvent.class)<br>  public void onRefresh() {<br>    ////do something if all apps have initialised<br>  }<br>}</pre><p><em>ContextClosedEvent:</em> Event published when the ApplicationContext is closed, using the close() method on the ApplicationContext. Closed here means that singletons are destroyed.</p><pre>@Component<br>public class AppEvents {<br><br>  @EventListener(ContextClosedEvent.class)<br>  public void onClosed() {<br>    ////do something if application Context closed<br>  }<br>}</pre><p><em>RequestHandledEvent:</em> A web-specific event telling all beans that an HTTP request has been serviced (i.e. this will be published <em>after</em> the request has been finished). Note that this event is only applicable for web applications using Spring’s DispatcherServlet.</p><pre>@Component<br>public class AppEvents {<br><br>  @EventListener(RequestHandledEvent.class)<br>  public void onRequest() {<br>    ////do something on HTTP request.<br>  }<br>}</pre><p>Example:</p><ul><li>Creating new application events by extending the <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationEvent.html"><em>ApplicationEvent</em></a> class.</li><li>Using <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html"><em>ApplicationEventPublisher</em></a> to notify all matching listeners registered of a specific application event.</li><li>Registering the event listeners using the <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/event/EventListener.html"><em>@EventListener</em></a> annotation and implementing the <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationListener.html"><em>ApplicationListener</em></a> interface.</li><li>If there are multiple listeners for a specific event then define the order using the <em>@Order</em> annotation.</li></ul><p>Sometimes in an application, we may want to add the capability for listening to specific application events and processing these events for various audit purposes. Examples of these events can be when a new record is added or deleted, or a certain kind of transaction is completed or rolled back.</p><ul><li>Creating an Application Event<br>An application event in Spring is represented by created by extending the <em>ApplicationEvent</em> class which is an <em>abstract</em> class. <br>For example, if we want to notify the listeners whenever a new <em>Order</em> is <em>placed</em> then we can create a custom class <em>OrderEvent</em> as follows:</li></ul><pre>public class OrderEvent extends ApplicationEvent {<br><br>  public OrderEvent(Order order) {<br>    super(order);<br>  }<br><br>  @Override<br>  public String toString() {<br>    return &quot;ApplicationEvent: New Order Placed :: &quot; + this.getSource();<br>  }<br>}</pre><ul><li>With later versions of Spring, extending the <em>ApplicationEvent</em> is not mandatory.</li></ul><pre>public class OrderEvent {<br><br>  private Order order;<br><br>  public OrderEvent(Order order) {<br>    this.order = order;<br>  }<br><br>  public Order getOrder() {<br>    return order;<br>  }<br><br>  @Override<br>  public String toString() {<br>    return &quot;ApplicationEvent: New Order Placed :: &quot; + this.order;<br>  }<br>}</pre><ul><li>Publishing an Application Event<br>The <em>ApplicationEventPublisher</em> interface encapsulates the whole event publication functionality. To access the <em>ApplicationEventPublisher</em> in a class, we may, optionally, implement the <em>ApplicationEventPublisherAware</em> interface in that class; else the Spring injects it automatically in the runtime.</li><li>After we have access to <em>ApplicationEventPublisher</em>, we can use the <em>applicationEventPublisher.publishEvent()</em> method which accepts an <em>ApplicationEvent</em> type as a method argument.</li></ul><pre>@Service<br>public class OrderService implements ApplicationEventPublisherAware {<br><br>  ApplicationEventPublisher applicationEventPublisher;<br><br>  @Override<br>  public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {<br>    this.applicationEventPublisher = applicationEventPublisher;<br>  }<br><br>  public OrderService(OrderRepository repository) {<br>    this.repository = repository;<br>  }<br><br>  public Order create(Order order) throws ApplicationException {<br>    Order newOrder = repository.save(Order);<br>    if (newOrder != null) {<br>      applicationEventPublisher.publishEvent(new OrderEvent(newOrder));   //Notify the listeners<br>      return newOrder;<br>    }<br>    throw new ApplicationException(&quot;Order could not be placed&quot;);<br>  }<br>}<br></pre><ul><li>Receiving an Application Event<br>We can listen to the application events in two ways i.e. using the <em>ApplicationListener</em> interface or using the <em>@EventListener</em> annotation.<br>To listen to certain events, a bean must implement the <em>ApplicationListener</em> interface and handle the events in the <em>onApplicationEvent()</em> method. Spring will notify a listener of all events, so you must filter the events by yourself.<br>If we use generics, Spring will deliver only messages that match the generic type parameter. In this example, we are using generics code to listen only to the <em>DeleteOrderEvent</em>.</li></ul><pre>@Component<br>public class DeleteOrderEventListener implements ApplicationListener&lt;DeleteOrderEvent&gt; {<br><br>  @Override<br>  public void onApplicationEvent(DeleteOrderEvent event) {<br>    log.info(event.toString());<br>  }<br>}</pre><ul><li>Using @EventListener annotation.<br>Since Spring 4.1, we can annotate a method with <em>@EventListener</em> and register the event listener of the type of method argument.</li></ul><pre>@Component<br>public class OrderEventsListener {<br><br>  @EventListener<br>  void handleOrderEvent(AddOrderEvent event) {<br>    log.info(event.toString());<br>  }<br><br>  @EventListener<br>  void handleDeleteOrderEvent(DeleteOrderEvent event) {<br>    log.info(event.toString());<br>  }<br>}<br>// or it can be written as below<br>@EventListener({OrderEvent.class, DeleteOrderEvent.class})<br>void handleOrderEvents(OrderEvent event) {<br>  log.info(event.toString());<br>}</pre><h4>Low-level resources and the application context:</h4><p>An application context is a ResourceLoader, able to be used to load Resources. A Resource is essentially a java.net.URL on steroids (in fact, it just wraps and uses a URL where appropriate), which can be used to obtain low-level resources from almost any location in a transparent fashion, including from the classpath, a filesystem location, anywhere describable with a standard URL, and some other variations. If the resource location string is a simple path without any special prefixes, where those resources come from is specific and appropriate to the actual application context type.</p><h4>BeanPostProcessor and BeanFactoryPostProcessor:</h4><ol><li>A bean implementing BeanPostProcessor operate on bean (or object) instances which means that when the Spring IoC container instantiates a bean instance then BeanPostProcessor interfaces do their work.</li><li>A bean implementing BeanFactoryPostProcessor is called when all bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans. This will let you have access to all the beans that you have defined in XML or that are annotated (scanned via component scan).</li></ol><h3>Differences:</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZOSVKmMPmQRNZg7X_Hggug.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=314a4889b132" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: Interceptor]]></title>
            <link>https://medium.com/@saiteja-erwa/spring-boot-interceptor-c9b90ddf3538?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/c9b90ddf3538</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[spring-boot]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Sun, 19 May 2024 01:26:48 GMT</pubDate>
            <atom:updated>2024-05-19T01:31:20.091Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Primary purpose:</em> <em>to intercept the incoming requests and response dispatch.</em></p><p>An interceptor is used to intercept and process a request before it reaches a controller and/or just before the response is sent back to the client. Interceptors can be used for various purposes, such as logging, authentication, authorization, performance monitoring, and other cross-cutting concerns.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*iAewQP2gExslbsWtC1ohaw.jpeg" /></figure><p><strong>HandlerInterceptor:</strong></p><p>Interceptors in Spring Boot are defined by implementing the <strong>HandlerInterceptor</strong> interface. The <strong>HandlerInterceptor</strong> interface defines three methods that you can override:</p><ol><li><strong>preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) </strong>:</li></ol><pre>default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)<br>   throws Exception {<br><br>  return true;<br> }</pre><p>This method is called before the actual handler (controller) method is executed. It can be used to perform operations before sending the request to the controller.</p><p>Dispatcher Servlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can decide to abort the execution chain or continue based on the return value true/false.</p><blockquote>true: It continues the execution chain.<br>false: It aborts the execution chain.</blockquote><p>2. <strong>postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) :</strong></p><pre>default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,<br>   @Nullable ModelAndView modelAndView) throws Exception {<br> }</pre><p>This method is called after the handler method is executed, but before the view is rendered.</p><p>DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors, with the handler itself at the end. With this method, each interceptor can post-process an execution, getting applied in inverse order of the execution chain.</p><p>3.<strong> afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) :</strong></p><pre>default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,<br>   @Nullable Exception ex) throws Exception {<br> }</pre><p>This method is called after the view is rendered. It can be used to perform cleanup operations, such as releasing resources.</p><p>Note: Will only be called if this interceptor’s preHandle method has successfully completed and returned true!</p><p>Example of an interceptor in spring boot:</p><pre>@Component<br>public class MediumInterceptor implements HandlerInterceptor {<br><br>  @Override<br>  public boolean preHandle(HttpServletRequest request, <br>                           HttpServletResponse response,<br>                           Object handler) {<br>    //Invoked before sending the request to the controller<br>    System.out.println(&quot;preHandle method called&quot;);<br>    return true;<br>  } <br><br>  @Override<br>  public void postHandle(HttpServletRequest request, <br>                         HttpServletResponse response,<br>                         Object handler,<br>                         ModelAndView modelAndView){<br>    //Invoked after processing the request and before the view is rendered.<br>    System.out.println(&quot;postHandle method called&quot;);<br>  }<br><br>  @Override<br>  public void afterCompletion(HttpServletRequest request, <br>                              HttpServletResponse response,<br>                              Object handler,<br>                              Exception ex) {<br>    //Invoked after view is rendered<br>    //Performs cleanup operation<br>    System.out.println(&quot;afterCompletion method called&quot;);<br>  }<br><br>}</pre><p>To register an interceptor, the configuration class implements an interface — “<em>WebMvcConfigurer” </em>which allows us to customize spring MVC configuration specific to our own needs, overriding its default behaviour.</p><pre>import org.springframework.context.annotation.Configuration;<br>import org.springframework.web.servlet.config.annotation.InterceptorRegistry;<br>import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;<br><br>@Configuration<br>public class WebConfig implements WebMvcConfigurer {<br><br>    @Override<br>    public void addInterceptors(InterceptorRegistry registry) {<br>        //This tells the InterceptorRegistry to register the provided class as the Interceptor<br>        registry.addInterceptor(new MediumInterceptor());<br>    }<br>}</pre><p>With this configuration, MediumInterceptor will be applied to every request processed by the Spring MVC dispatcher.</p><p>We can also specify URL patterns to which the interceptor should apply or exclude certain patterns using the methods addPathPatterns and excludePathPatterns, respectively:</p><pre>registry.addInterceptor(new MediumInterceptor()).addPathPatterns(&quot;/medium/api/**&quot;);</pre><p>This would only apply MediumInterceptor to paths that start with medium/api/.</p><p><strong><em>Interceptors offer a powerful way to implement cross-cutting logic in Spring Boot applications in a clean and decoupled manner.</em></strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c9b90ddf3538" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: @PostConstruct and @PreDestroy]]></title>
            <link>https://medium.com/@saiteja-erwa/spring-boot-postconstruct-and-predestroy-69f364d9124a?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/69f364d9124a</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[java]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Sat, 18 May 2024 07:00:47 GMT</pubDate>
            <atom:updated>2024-05-18T09:22:31.372Z</atom:updated>
            <content:encoded><![CDATA[<p><strong><em>Primary purpose:</em></strong><em> These annotations are used to define methods that should be executed after the initialization of the bean and just before the bean is removed from the container respectively.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TjyxgFD9tI505_arusCJKw.png" /></figure><p><strong>@PostConstruct:</strong></p><p>The @PostContruct annotation is used on a method that needs to be executed after a bean is fully initialised, i.e., after all the dependency injection is done.</p><ul><li>It is called only once in the entire bean life cycle after all the initializations.</li><li>This annotation is typically used for setup tasks that need to be performed.</li></ul><pre>import jakarta.annotation.PostConstruct;<br><br>@Component<br>public class CommonConfiguration {<br><br>  @PostConstruct<br>  public class init() {<br>    // Initialization logic goes here<br>    // like setting some threshold values or setting some properties...<br>  }<br>}</pre><ul><li>The method on which the PostConstruct annotation is applied may be public, protected, package private or private.</li><li>The method must not be static except for the application client.</li></ul><blockquote>This is because the lifecycle of application clients is different from other Jakarta EE components, and the application client container ensures that the static method is called appropriately.</blockquote><ul><li>The method should not be final.</li></ul><p><strong>@PreDestroy:</strong></p><p>The @PreDestroy annotation is used on a method that is called just before a bean is removed from the Spring container and destroyed. This method is used for cleanup purposes, such as releasing resources that the bean might be holding (like closing file resources or database connections).</p><pre>import jakarta.annotation.PreDestroy;<br><br>@Component<br>public class CacheConfiguration {<br><br>  @PreDestroy<br>  public class destroy() {<br>    // cleanup logic goes here<br>    // closing file resources or database connections, closing cache manager<br>    HazleCast.shutdownAll();<br>  }<br>}</pre><ul><li>The method on which PreDestroy is applied may be public, protected, package private or private.</li><li>The method must not be static.</li><li>The method should not be final.</li></ul><p>In addition to these annotations, Spring also provides interfaces such as “InitializingBean” and “DisposableBean” with “afterPropertiesSet” and “destroy” methods, respectively. You can use these interfaces as an alternative to @PostConstruct and @PreDestroy, although the annotation-based approach is typically preferred for its simplicity and clarity.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=69f364d9124a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Feign Client: RequestInterceptors]]></title>
            <link>https://medium.com/@saiteja-erwa/feign-client-requestinterceptors-2435f4e5cfb1?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/2435f4e5cfb1</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[feignclient]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Fri, 17 May 2024 12:06:40 GMT</pubDate>
            <atom:updated>2024-05-18T11:03:36.289Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Primary purpose — “to add headers to all requests”.</em></p><h3>RequestInterceptors</h3><p>Zero or more RequestInterceptors may be configured for purposes such as adding headers to all requests. No guarantees are given about the order in which interceptors are applied.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Cpmz_8P3zeruLWOc" /><figcaption>Photo by Clément Hélardot on Unsplash</figcaption></figure><p><em>use-case: </em><br>Example: If service-A is consuming with service-B using feignClient<br>1. Create a request interceptor</p><pre>public class AddHeaderInterceptor implements RequestIterceptor {<br><br>@Override<br>public class apply(RequestTemplate requestTemplate) {<br>  requestTemplate.Header(&quot;trackingId&quot;, &quot;124314..&quot;);<br>}</pre><p>2. Create a common feignConfig class where we configure a bean for this AddHeaderInterceptor.</p><pre>public class FeignConfig {<br><br>  @Bean<br>  public AddHeaderInterceptor commonAddHeaderInterceptro() {<br>      return new AddHeaderInterceptor();<br>  }<br>  <br>}</pre><p>3. In actual FeignClient use this FeignConfig.</p><pre>@FeignClient(value=&quot;service-b&quot;, url=&quot;placeholder-url&quot;, configuration=FeignConfig.class)<br>public interface commonFiegnClient {<br>  //requests to service-b<br>}</pre><p>Interceptor will be called for every request, and add data using the provided RequestTemplate.<br>likewise, we can use this FeignConfig for other service consumption.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2435f4e5cfb1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git: Merge Vs Rebase]]></title>
            <link>https://medium.com/@saiteja-erwa/git-merge-vs-rebase-0ec1820d8ab4?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/0ec1820d8ab4</guid>
            <category><![CDATA[git]]></category>
            <category><![CDATA[version-control]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Fri, 17 May 2024 06:58:37 GMT</pubDate>
            <atom:updated>2024-05-18T14:46:08.825Z</atom:updated>
            <content:encoded><![CDATA[<p>Once we have finished developing the feature, we’ll want to get the feature branch back into the main branch. Few options to do this as below.</p><p><strong><em>git merge: </em></strong>pulls in the latest changes from the main into the feature branch creating a new “merge commit” in the process. That binds the histories of both branches. If we do this a lot, we end up with lots of merge commits, which can make the history a bit messy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/739/1*7kBWP4BAc7vhav78WrR71w.png" /><figcaption>Git Merge</figcaption></figure><p><strong><em>git rebase:</em></strong><em> </em>changes the base of our feature branch to the latest commit on the main and then replays our changes from there. It gives us a linear commit history. The branch changes onto the tip of the main and then performs a fast-forward merge. This is like straightening, so it’s all in one line.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*znz0mngayEplulzlmupOTQ.png" /><figcaption>Git Rebase</figcaption></figure><p><strong>Summary:</strong><br><strong>“git merge”</strong> gives us a complete picture of the commit history and branch evolution.</p><p><em>pros: </em><br>1. Preserve commit history.</p><p><em>cons:</em><br>1. Make the history messy.</p><p><strong>“git rebase”</strong> tidies up history by moving commits to the main branch tip.</p><p><em>pros: </em><br>1. Allows for a cleaner commit history.<br>2. Provides a linear commit timeline.</p><p><em>cons:</em><br>1. Reduced traceability.<br>2. Solving rebase conflicts is usually harder than solving merge conflicts.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0ec1820d8ab4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring Boot: Lifecycle of Prototype Bean Scope]]></title>
            <link>https://medium.com/@saiteja-erwa/bean-scope-prototype-in-spring-boot-443b740f964f?source=rss-3cf75fe15ffc------2</link>
            <guid isPermaLink="false">https://medium.com/p/443b740f964f</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[spring]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Saiteja Erwa]]></dc:creator>
            <pubDate>Thu, 16 May 2024 17:11:36 GMT</pubDate>
            <atom:updated>2024-05-19T11:38:34.458Z</atom:updated>
            <content:encoded><![CDATA[<h3>Spring Boot: Bean Scope Prototype</h3><p>The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made. That is, the bean is injected into another bean or you request it through a getBean() method call on the container. As a rule, you should use the prototype scope for all stateful beans and the singleton scope for stateless beans.</p><p>We can define the scope of a bean as a prototype using the scope=”prototype” attribute of the element or <br>using @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) annotation.</p><pre>@Configuration<br>public class ApplcationConfig {<br><br>    @Bean<br>    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)<br>    public MessageService messageService() {<br>        return new FBMessageService();<br>    }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*atbo-oT10dYzJOi_Bg4CTQ.png" /></figure><p><strong><em>Lifecycle:</em></strong></p><p>Spring does not manage the complete lifecycle of a prototype bean. The container instantiates, configures, and otherwise assembles a prototype object and hands it to the client, with no further record of that prototype instance.</p><p>Although initialisation lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. For prototype bean @PreDestroy method is not invoked.</p><p>The reason behind this is simple: Spring manages the full lifecycle of Singleton beans but with Prototype beans, it hands over the bean after initialisation. The destruction or cleanup of prototype beans falls outside of Spring’s responsibility.</p><p>The client code must clean up prototype-scoped objects and release expensive resources that the prototype beans hold.</p><p>Use a custom bean-post-processor which holds a reference to beans that need to be cleaned up.</p><p>Implement the following interfaces:</p><ol><li><strong>ApplicationContextAware</strong><br> This interface provides a callback method which receives a ApplicationContext object. This object is used in the post-processor class to identify all prototype beans via its .isPrototype(String beanName) method.</li><li><strong>DisposableBean</strong><br> This interface provides a destroy() callback method invoked by the Spring container. We will call the destroy() methods of all our prototype beans from within this method.</li><li><strong>BeanPostProcessor</strong><br> Implementing this interface provides access to post-process callbacks from within which, we prepare an internal List&lt;Object&gt; of all prototype objects instantiated by the Spring container. We will later loop through this List&lt;Object&gt; to destroy each of our prototype beans.</li><li>Finally implement the DisposableBean interface in each of your prototype beans, providing the destroy() method required by this contract.</li></ol><pre>package com.cisco.cjp.credential.service.it.common;<br><br>import org.springframework.beans.BeansException;<br>import org.springframework.beans.factory.DisposableBean;<br>import org.springframework.beans.factory.config.BeanPostProcessor;<br>import org.springframework.context.ApplicationContext;<br>import org.springframework.context.ApplicationContextAware;<br><br>import java.util.LinkedList;<br>import java.util.List;<br><br>public class PrototypeBeanPostProcessor implements BeanPostProcessor, DisposableBean, ApplicationContextAware {<br><br>    private ApplicationContext context;<br>    List&lt;Object&gt; prototypeBeans = new LinkedList&lt;Object&gt;();<br><br>    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {<br>        if (context.isPrototype(beanName)) {<br>            synchronized (prototypeBeans) {<br>                prototypeBeans.add(bean);<br>            }<br>        }<br><br>        return bean;<br>    }<br><br>    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {<br>        this.context = applicationContext;<br>    }<br><br>    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {<br>        return bean;<br>    }<br><br>    public void destroy() throws Exception {<br>        synchronized (prototypeBeans) {<br>            for (Object bean : prototypeBeans) {<br>                if (bean instanceof DisposableBean) {<br>                    DisposableBean disposable = (DisposableBean)bean;<br>                    try {<br>                        disposable.destroy();<br>                    } catch (Exception e) {<br>                        e.printStackTrace();<br>                    }<br>                }<br>            }<br>            prototypeBeans.clear();<br>        }<br>    }<br>}<br><br></pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=443b740f964f" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>