Today we learned to create a spring project in Spring initializer.
Here we learnt metadata is data about data, some of metadata in maven is artifact,groupid and version.
we also learned about maven project structure and adding spring web dependency. Spring web gives tomcat automatically, whereas in eclipse we as a programmer explicitly add apache tomcat server and bring it up. spring web helps to withhold tomcat server and container takes care of bringing the server up. it helps developer to concentrate on business log instead of working in bringing the server up. Its a great feature of spring boot.
Exploring logs:
application.properties
- server.port = 8080 //port in which localhost will be accessed
- logging.level.root=INFO //logger prints all abstract information into the console.
- logging.level.root=DEBUG // It prints all debug informations.errors.and INFO into the console.
- logging.level.root=TRACE// It prints fine-grained logic flow. 5.logging.level.com.spring.LearningDemo = DEBUG //If we want to print only our package logs, we can do it. 6.If we want to have a external logging file in local disk we use below code in application.properties. logging.file.name = myapp.log logging.file.path="/E:Spring projects/LearningDemo"
- In production we use logging.level.root=INFO to avoid unneccesary loggings. we use DEBUG only when we want identify a bug.
context pat is the base URL of app. here http://localhost:8080/index.
Annotations:
@Controller
Container idetifies the mentioned class as container using this annotation.
@Controller
public class LearningFrontController {
public String getResponseFromLearningFrontController(){
return "Welcome to SpringBootFrontController";
}
}
In core Java programmer has to initialise an object to call any method from one class to another. whereas in spring and spring boot container takes of creating instances, programmer can concentrate on the business logic.
A project can have any no of controllers, we can differentiate them using requestmapping annotaion.
@Controller
@RequestMapping("First")
public class LearningFrontController {
private static final Logger log= LoggerFactory.getLogger(LearningFrontController.class);
public String getResponseFromLearningFrontController(){
log.info("LearningFrontController started");
log.debug("Debug:LearningFrontController started");
log.debug("Debug:LearningFrontController completed");
return "Welcome to SpringBootFrontController";
}
}
similarly a single container can have any no of methods so we exlplicitly differentiate the method using @RequestMapping("/add")
@RequestMapping("/add/{a}/{b}")
@ResponseBody
public String getAddResponseFromLearningFrontController(@PathVariable int a,@PathVariable int b){
log.info("LearningFrontController started");
log.debug("Debug:LearningFrontController started");
int c=a+b;
log.debug("Debug:LearningFrontController completed");
log.debug("Debug:LearningFrontController completed");
return "Addition is "+c;
}
This method usually returns the view name and view resolver returns it to the client but when we want to return a value and inform the container to print the returned value as content of the page, we use "@ResponseBody"
@RequestMapping("/Login/{username}/{password}")
//@ResponseBody
public String Login(@PathVariable String username,@PathVariable String password)
{
log.debug("Debug:welcomeUser started");
String name1 =username;
log.debug("Debug:welcomeUser completed");
return "welcome "+username;
}
@RestController
Combination of both Responsebody and controller.
when all methods in the container uses response body, then we can mention one annotation at the top of the controller.
@RestController
@RequestMapping("/second")
public class LearningFrontREquestController {
private static final Logger log= LoggerFactory.getLogger(com.learning.LearningDemo.LearningFrontController.class);
public String getResponseFromLearningFrontController(){
log.info("LearningFrontController started");
log.debug("Debug:LearningFrontRequstController started");
log.debug("Debug:LearningFrontrequstController completed");
return "Welcome to SpringBootFrontController";
}
Difference between Pathvariable and RequestPAram
@PathVariable
1.user is sending input to the method in URL.
- Service will fetch this input from the url and handles in method when @Pathvariable is mentioned.
- URL format is http:/localhost::8080/firstControllerNameMappe/CallingMethoMap/{input1}/{input2}
- Its param are unique value like userid
- It can take only 20 arguments & It cannot take null values. if values are not sent in URL,it will throw 404 error.
6.Using java.util.Optional: You can wrap the parameter in an Optional type (e.g., Optional id). If the path variable is missing from the URI, the value will be Optional.empty() rather than null.
7.Handling with a Map: You can use a Map to capture all path variables. If a specific key is missing, its value in the map will be null.
8.Using pathVariableOrNull (WebFlux): For applications using Spring WebFlux, the ServerRequest interface provides a pathVariableOrNull() helper method to handle missing variables gracefully.
_@RequestParam
_1. Service will receive inputs from URL & URL is in below format
http://localhost:8080/firstControllerNameMappe/CallingMethoMap?input1=6&input2=9
- Request can have any no of arguments & it wont represent unique id
- it usually fetches a lengthy data ex:getting all the students name starting in K. It obviusly returns n no of data
- It wont take empty arguments
@RequestBody
when the input is in JSON format. we use RequestBody.
JAckson library helps to convet JSON to object inside spring boot application and it also converts the object to JSON and send it back to POSTMAN.
@RequestMapping("/divide")
//@ResponseBody
public Student getDivideService(@RequestBody Student student){
log.info("inside LearningFrontController.getSubtractService");
int a=student.getFirstValue();
int b=student.getSecondValue();
log.info("a "+a +"b "+b);
if((a!=0)&&(b!=0)) {
double divided = learningDemoService.divitionService(a, b);
student.setDivided(divided);
}
student.setName(student.getName().toUpperCase().trim());
log.info(response);
log.info("exiting LearningFrontController.getSubtractService");
return student;
}
}
Object creation:
In java:
To have interaction between classes we will create object using new keyword.
Student object=new Student();
In Spring framework.
we will declare in XML
In spring boot we have two annotations
- Component
- Bean Component:
- It is declared in class level. If @Comparable is mentioned on top of class, An object will be create on compile time.
- Auto-detected via classpath scanning.
- Limited; uses Spring's default instantiation.
- Has specialized forms: @Service, @Repository, @Controller,@Configuration.
- @Component is an interface
Bean:
- It is declared in Method Level. It is declared in class which has @Configuration annotation on top of it.
- All classe with @Configuration annotation is loaded and all the methods,construtors are loaded and all objects mentioned in the constructors are created.
- It can be done in three ways setter injection, field injection, constructor injection. Field injection is not advisable.
- programmer can have full control over the class.
- we can create object for third party classes using Bean even library files. Snippet 1 @bean(initMethod = "init", destroyMethod = "cleanup") public MyService myService() { return new MyService(); } Ex import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
private static final Logger log= LoggerFactory.getLogger(Config.class);
@bean
Student getStudent(){
log.info("inside student Bean creation config ");
return new Student();
}
}
How it works internally
Application starts:
SpringApplication.run(MyApp.class, args);
Spring Boot:
- Scans classes (@ComponentScan)
- Reads config (@Configuration)
- Applies auto-config (@EnableAutoConfiguration)
- Beans are created and stored in:
- 👉 ApplicationContext (Spring Container
@PostConstruct:
we use postconstruct when we want to add values to an object immediately after initialisation.
When it runs
After the bean is created and dependencies are injected
✅ Purpose
Initialization logic
Setting default values
Opening resources
@PostConstruct
public void init(){
log.info("init method called");
studentFromBeanConfig.setName("Karthi");
studentFromBeanConfig.setLoginStatus(true);
}
@PreDestroy
It is used to delete values before destroying the same object.
@PreDestroy
public void preDestroy(){
System.out.println("Values are destroyed");
}
Lifecycle of Bean :
Bean Created → @PostConstruct → Bean in Use → @PreDestroy → Bean Destroyed
Important Points for PreDestroy
_Method must be:
_
- public
- void
- No arguments
- Works only for singleton beans by default
- Triggered when: Application stops Context is closed.
@primary & @Qualifier
In Spring and Spring Boot, both @primary and @Qualifier are used to resolve autowiring ambiguity when multiple beans of the same type exist in the application context.
Primary Annotation:
- The @primary annotation in Spring is used to designate a primary bean among multiple beans of the same type. When a primary bean is defined using @primary, it is preferred for injection when no specific bean name or qualifier is provided.
-
this is a class level annotation
Qualifier Annotation:
On the other hand, the @Qualifier annotation is used to specify the exact bean to be injected when multiple beans of the same type are present. It works in conjunction with bean names or custom qualifiers to resolve ambiguity and specify the desired bean for injection.
Example:
@RestController
@RequestMapping("student")
public class StudentPrimaryAndQualiferService {
@Autowired
@Qualifier("JavaCoursestuent")
StudentInterface studentInterface;@RequestMapping("/getStudentInferface")
public String getStudentInterface(){
return "Name: "+studentInterface.getName()+ "Roll No :" +studentInterface.getRollNo();
}
}
package LearningBeanConfig;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@primary
public class SchoolStudent implements StudentInterface{
@override
public String getName() {
return "SchoolStudent";
}
@Override
public String getRollNo() {
return "DAV-11";
}
}
package LearningBeanConfig;
import com.Learning.LearningDemo.LearningDemoApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component(value="JavaCoursestuent")
public class JavaCourseStu implements StudentInterface {
private static final Logger log = LoggerFactory.getLogger(JavaCourseStu.class);
@Override
public String getName() {
log.info("JavaCoursestuent.getNAme starts");
return "Java Course StudentInterface ";
}
@Override
public String getRollNo() {
log.info("JavaCoursestuent.getRollNo starts");
return "RollNo1";
}
}
Top comments (0)