$show=/label

Building Calculator Application in Spring Boot - @Bean Example

SHARE:

A quick spring boot example to build a simple calculator application with the power of @Bean Annotation.



1. Introduction


In this tutorial, We'll learn how to build a simple calculator application using spring boot framework. This is mainly demonstrating to understand @Bean and @Componet annotations usage and how the dependencies are getting injected by the application context.

First, We will see the creation of the calculator interface and its implementation classes.

Next, Creating the Bean with @Bean annotation using the method injection technique.

Finally, Understanding the execution and dependency injections.

Further, You can read examples of bean creation using @Component and @Bean annotations.




2. Creating a Calculator Application


By default, Spring boot does autoconfiguration and detects all @Componet components.
Additionally, you can use @Bean annotation with the help of factory methods. @Bean gives us the flexibility of construction of the bean.

But, here you have to remember is the always method name is considered as bean name so we have to keep the bean name as method name as below.

The below is just an example and not part of the calculator program. Do not get confused.

[@Bean
public Student student(Address a){
return new Student(a);
}]

2.1 Creating Operation Base Interface


[package com.javaprogramto.caculator.calculatordemo;
public interface Operation {
long apply(long a, long b);
boolean valid(char operator);
}]

2.2 Creating Operation Implementation classes


Now, Adding three operations for Addition, multiplication, and division operations. But, this still can be extensible for subtraction and other operations log, root operations as well.

2.2.1 Addition Class


[import org.springframework.stereotype.Component;
@Component
public class Addition implements Operation {
@Override
public long apply(long a, long b) {
return a + b;
}
@Override
public boolean valid(char operator) {
return '+' == operator;
}
}]


2.2.2 Division Class


[import org.springframework.stereotype.Component;
@Component
public class Division implements Operation {
@Override
public long apply(long a, long b) {
return a / b;
}
@Override
public boolean valid(char operator) {
return '/' == operator;
}
}]


2.2.3 Multiplication Class


[import org.springframework.stereotype.Component;
@Component
public class Multiplication implements Operation {
@Override
public long apply(long a, long b) {
return a * b;
}
@Override
public boolean valid(char operator) {
return '*' == operator;
}
}]


2.3 Creating Calculator class


This class does the basic operation for the given values.

[package com.javaprogramto.caculator.calculatordemo;
public class Calculator {
Logger logger = LoggerFactory.getLogger(getClass());
private List<Operation> operations;
public Calculator(List<Operation> operations) {
super();
this.operations = operations;
}
public void calculate(long a, long b, char operator) {
for (Operation o : operations) {
if (o.valid(operator)) {
long output = o.apply(a, b);
logger.info(a + " " + operator + " " + b + " = " + output);
return;
}
throw new IllegalArgumentException("Illegal operation for operator : "+operator);
}
}
}]


This class is dependent on the List<Operation> so we should tell to spring to inject all of these.

Fist of all, it checks if the given operation is valid then valid() method returns true and further calls apply() method that does actual core logic for calculation.

If in case given operator is not matching to the list of available Operation's then it will throw IllegalArgumentException exception.


2.4 Main SpringBootApplication


In this application, Created a bean with @Bean annotation with the method

[package com.javaprogramto.caculator.calculatordemo;
import java.util.List;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class CalculatorDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CalculatorDemoApplication.class, args);
}
@Bean
public Calculator calculator(List<Operation> operations) {
return new Calculator(operations);
}
@Bean
public ApplicationRunner applicationRunner(Calculator calculator) {
return args -> {
calculator.calculate(10, 20, '+');
calculator.calculate(100, 20, '/');
calculator.calculate(10, 3, '*');
};
}
}]

Output:

[2020-04-25 12:46:45.751  INFO 50913 --- [           main] c.j.c.c.CalculatorDemoApplication        : Starting CalculatorDemoApplication on -Pro-2.local with PID 50913 (/Users/venkateshn/Documents/VenkY/blog/workspace/CaclulatorExample/target/classes started by venkateshn in /Users/venkateshn/Documents/VenkY/blog/workspace/CaclulatorExample)
2020-04-25 12:46:45.754  INFO 50913 --- [           main] c.j.c.c.CalculatorDemoApplication        : No active profile set, falling back to default profiles: default
2020-04-25 12:46:46.380  INFO 50913 --- [           main] c.j.c.c.CalculatorDemoApplication        : Started CalculatorDemoApplication in 0.914 seconds (JVM running for 1.291)
2020-04-25 12:46:46.382  INFO 50913 --- [           main] c.j.caculator.calculatordemo.Calculator  : 10 + 20 = 30
2020-04-25 12:46:46.382  INFO 50913 --- [           main] c.j.caculator.calculatordemo.Calculator  : 100 / 20 = 5
2020-04-25 12:46:46.382  INFO 50913 --- [           main] c.j.caculator.calculatordemo.Calculator  : 10 * 3 = 30]

Here, Spring Boot will automatically detect all classes of Operation implementations with @Bean annotation.

Note: Instead of using @Bean, you can @Component on the Calculator class and @Autowired on the right constructors if there are multiple constructors.

If you pass any other operations than valid then it will throw runtime exception as below because it does not match with the Operation implementors classes.

[calculator.calculate(10, 3, '-');]

Output:


[java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:778) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:765) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at com.javaprogramto.caculator.calculatordemo.CalculatorDemoApplication.main(CalculatorDemoApplication.java:15) [classes/:na]
Caused by: java.lang.IllegalArgumentException: Illegal operation for operator : -
at com.javaprogramto.caculator.calculatordemo.Calculator.calculate(Calculator.java:31) ~[classes/:na]
at com.javaprogramto.caculator.calculatordemo.CalculatorDemoApplication.lambda$0(CalculatorDemoApplication.java:33) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:775) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
... 5 common frames omitted]


If you define the @Componet and @Bean method these two and run the application will produce the below error.


[2020-04-25 13:06:35.353  WARN 51621 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'calculator' defined in com.javaprogramto.caculator.calculatordemo.CalculatorDemoApplication: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=calculatorDemoApplication; factoryMethodName=calculator; initMethodName=null; destroyMethodName=(inferred); defined in com.javaprogramto.caculator.calculatordemo.CalculatorDemoApplication] for bean 'calculator': There is already [Generic bean: class [com.javaprogramto.caculator.calculatordemo.Calculator]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/venkateshn/Documents/VenkY/blog/workspace/CaclulatorExample/target/classes/com/javaprogramto/caculator/calculatordemo/Calculator.class]] bound.
2020-04-25 13:06:35.371  INFO 51621 --- [           main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-04-25 13:06:35.372 ERROR 51621 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'calculator', defined in com.javaprogramto.caculator.calculatordemo.CalculatorDemoApplication, could not be registered. A bean with that name has already been defined in file [/Users/venkateshn/Documents/VenkY/blog/workspace/CaclulatorExample/target/classes/com/javaprogramto/caculator/calculatordemo/Calculator.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true]

This error is produced because of calculator bean is defined twice and can not be used the same name for another bean. So, either we need to provide a different name for the bean as below or need to provide overriding property to true.

application.properties

[spring.main.allow-bean-definition-overriding=true]


[@Bean("cal")
public Calculator calculator(List<Operation> operations) {
return new Calculator(operations);
}]


4. Conclusion


In conclusion, We've seen how to perform simple calculator operations in spring boot with the power of @Bean and @Componet annotations. And also we can extend the functionalities for other operators just providing the implementations for Operation interface.

As usual, the complete code is over GitHub and you can download from below links.

[lock]

[View on GitHub ##eye##]

[Download ##file-download##]

[/lock]

Spring Boot Calculator Application


  • [accordion]
    • Operation.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        public interface Operation {
        
         long apply(long a, long b);
        
         boolean valid(char operator);
        
        }
    • Addition.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        import org.springframework.stereotype.Component;
        
        @Component
        public class Addition implements Operation {
        
         @Override
         public long apply(long a, long b) {
        
          return a + b;
         }
        
         @Override
         public boolean valid(char operator) {
        
          return '+' == operator;
         }
        
        }
    • Division.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        import org.springframework.stereotype.Component;
        
        @Component
        public class Division implements Operation {
        
         @Override
         public long apply(long a, long b) {
        
          return a / b;
         }
        
         @Override
         public boolean valid(char operator) {
        
          return '/' == operator;
         }
        }
    • Multiplication.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        import org.springframework.stereotype.Component;
        
        @Component
        public class Multiplication implements Operation {
         @Override
         public long apply(long a, long b) {
        
          return a * b;
         }
        
         @Override
         public boolean valid(char operator) {
        
          return '*' == operator;
         }
        }
    • Calculator.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        import java.util.List;
        
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.stereotype.Component;
        
        //@Component
        public class Calculator {
        
         Logger logger = LoggerFactory.getLogger(getClass());
        
         private List<Operation> operations;
        
         public Calculator(List<Operation> operations) {
          super();
          this.operations = operations;
         }
        
         public void calculate(long a, long b, char operator) {
        
          for (Operation o : operations) {
           if (o.valid(operator)) {
        
            long output = o.apply(a, b);
            logger.info(a + " " + operator + " " + b + " = " + output);
            return;
           }
          }
          throw new IllegalArgumentException("Illegal operation for operator : " + operator);
         }
        
        }
    • CalculatorDemoApplication.java
      • package com.javaprogramto.caculator.calculatordemo;
        
        import java.util.List;
        
        import org.springframework.boot.ApplicationRunner;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.context.annotation.Bean;
        
        @SpringBootApplication
        public class CalculatorDemoApplication {
        
         public static void main(String[] args) {
          SpringApplication.run(CalculatorDemoApplication.class, args);
        
         }
        
         //@Bean("cal")
         @Bean
         public Calculator calculator(List operations) {
        
          return new Calculator(operations);
         }
        
         @Bean
         public ApplicationRunner applicationRunner(Calculator calculator) {
        
          return args -> {
        
           calculator.calculate(10, 20, '+');
           calculator.calculate(100, 20, '/');
           calculator.calculate(10, 3, '*');
           //calculator.calculate(10, 3, '-');
          };
        
         }
        
        }
        

COMMENTS

BLOGGER

About Us

Author: Venkatesh - I love to learn and share the technical stuff.
Name

accumulo,1,ActiveMQ,2,Adsense,1,API,37,ArrayList,18,Arrays,24,Bean Creation,3,Bean Scopes,1,BiConsumer,1,Blogger Tips,1,Books,1,C Programming,1,Collection,8,Collections,37,Collector,1,Command Line,1,Comparator,1,Compile Errors,1,Configurations,7,Constants,1,Control Statements,8,Conversions,6,Core Java,149,Corona India,1,Create,2,CSS,1,Date,3,Date Time API,38,Dictionary,1,Difference,2,Download,1,Eclipse,3,Efficiently,1,Error,1,Errors,1,Exceptions,8,Fast,1,Files,17,Float,1,Font,1,Form,1,Freshers,1,Function,3,Functional Interface,2,Garbage Collector,1,Generics,4,Git,9,Grant,1,Grep,1,HashMap,2,HomeBrew,2,HTML,2,HttpClient,2,Immutable,1,Installation,1,Interview Questions,6,Iterate,2,Jackson API,3,Java,32,Java 10,1,Java 11,6,Java 12,5,Java 13,2,Java 14,2,Java 8,128,Java 8 Difference,2,Java 8 Stream Conversions,4,java 8 Stream Examples,12,Java 9,1,Java Conversions,14,Java Design Patterns,1,Java Files,1,Java Program,3,Java Programs,114,Java Spark,1,java.lang,4,java.util. function,1,JavaScript,1,jQuery,1,Kotlin,11,Kotlin Conversions,6,Kotlin Programs,10,Lambda,2,lang,29,Leap Year,1,live updates,1,LocalDate,1,Logging,1,Mac OS,3,Math,1,Matrix,6,Maven,1,Method References,1,Mockito,1,MongoDB,3,New Features,1,Operations,1,Optional,6,Oracle,5,Oracle 18C,1,Partition,1,Patterns,1,Programs,1,Property,1,Python,2,Quarkus,1,Read,1,Real Time,1,Recursion,2,Remove,2,Rest API,1,Schedules,1,Serialization,1,Servlet,2,Sort,1,Sorting Techniques,8,Spring,2,Spring Boot,23,Spring Email,1,Spring MVC,1,Streams,31,String,61,String Programs,28,String Revese,1,StringBuilder,1,Swing,1,System,1,Tags,1,Threads,11,Tomcat,1,Tomcat 8,1,Troubleshoot,26,Unix,3,Updates,3,util,5,While Loop,1,
ltr
item
JavaProgramTo.com: Building Calculator Application in Spring Boot - @Bean Example
Building Calculator Application in Spring Boot - @Bean Example
A quick spring boot example to build a simple calculator application with the power of @Bean Annotation.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHBk_IJs76XGlHMii-P5OdWPKfpi9h1WWq5Cra5wmQC84DvVZSSBGFfaZKWz_gAB5qmoOQB0rGpqCQ08B4C6fvWRsnXhWGD0plkw7ogKN8Dsbvq98oTr0LDPCdE5T2kYuWBHE2X3M1FjY/s640/Building+Calculator+Application+in+Spring+Boot+-+%2540Bean+Example.png
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHBk_IJs76XGlHMii-P5OdWPKfpi9h1WWq5Cra5wmQC84DvVZSSBGFfaZKWz_gAB5qmoOQB0rGpqCQ08B4C6fvWRsnXhWGD0plkw7ogKN8Dsbvq98oTr0LDPCdE5T2kYuWBHE2X3M1FjY/s72-c/Building+Calculator+Application+in+Spring+Boot+-+%2540Bean+Example.png
JavaProgramTo.com
https://www.javaprogramto.com/2020/04/spring-boot-calculator-example.html
https://www.javaprogramto.com/
https://www.javaprogramto.com/
https://www.javaprogramto.com/2020/04/spring-boot-calculator-example.html
true
3124782013468838591
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content