Spring Action Notes (1) Getting to Know Spring

foreword

The decision to blog was inspired by "Soft Skills - The Way to Survive Beyond Code", and I know the benefits of blogging to benefit others and oneself.

The main language I used before was not java, but c#, and I didn't learn Spring because I wanted to switch to java. I think learning a framework is not only about knowing how to use the framework, but more importantly understanding the idea behind the framework, which is not limited by language. After reading the first chapter of "Spring Action", I have gained a lot, and I have also understood some of the thoughts that have been vague before. It can be said that I have gained a lot. I will stick to this blog series and share what I have gained. Cut to the chase below.

Spring Mission

Simplifying java development is the ultimate goal of the Spring framework. The seemingly simple words are not easy to implement. Spring subverts many frameworks before java in one fell swoop, drawing a fresh and beautiful landscape. Spring has made efforts to make the code more concise from the following aspects:

  • Stimulate the potential of POJO without invading the code.
  • Loose coupling through dependency injection and interface orientation
  • Declarative programming based on aspects and conventions
  • Reduce boilerplate code with aspects and templates

Stimulate the potential of POJO without invading the code.

    In the past, many frameworks required users to inherit framework interfaces or classes, which made developers need more code to adapt to the framework. Spring allows developers to focus only on the business itself. POJO (Plain Ordinary Java Object) is a simple java class, and there is no need to write too much unnecessary code for the adaptation framework. Below are two examples:

Procedure 1: EJB 2.1 enforces methods you don't need at all

public class HelloWorldBean implements SessionBean {
    public void ejbActivate(){}   // business unrelated code
    public void ejbPassivate(){}
    public void ejbRemove(){}
    public void setSessionContext(SessionContext ctx){}
    public void ejbCreate(){}

    public String sayHello() {
        return "Hello World";
    }
}

Program 2: Spring concise code

public class HelloWorldBean {
    public String sayHello() {
        return "Hello World";
    }
}

Loose coupling through dependency injection and interface orientation

To understand and understand dependency injection, first understand the difference between interface-oriented programming and implementation-oriented programming.

The following is a simple example, the interface-oriented car class (CarA) relies on the wheel (IWheel) with the function of running (Run), as long as the wheels of any manufacturer that conforms to the interface can be installed in the car A, I want to replace the wheels in the future , no need to re-modify the car architecture. The implementation-oriented programming of Car B (CarB) relies on a specific wheel implementation (WhellA). If more advanced wheels come out in the future, Car B can only meet each other unless it reinvents itself. So interface-oriented programming makes classes loosely coupled.

Program 3: Comparison of Interface-Oriented Programming and Implementation-Oriented Programming

// programming for the interface
public class CarA{
    Iwheel whell;  
    
    public Run(){
        whell.Run();
    }
}

// implementation-oriented programming
public class CarB{
    WhellA whell;  

    public Run(){
        whell.Run();
    }
}

So what is the relationship between dependency injection and interface-oriented programming? Where did the wheels of car A in the example above come from? If it is new inside the car, it still depends on the specific implementation class. In the future, if you change the wheel, you still need to modify the car class. In the following example, the wheel that car A depends on is injected by the constructor, so that the specific wheel to be used is handed over to the assembly of the car. However, the manufacturer of the car frame does not care about the choice of wheels and where they come from. It is enough to know that the wheels can achieve the Run function they want. In this way, car assemblers can assemble various cars (sports cars, ordinary cars, off-road vehicles) according to their own preferences, so dependency injection is an implementation of interface-oriented programming. In addition to constructor injection, dependency injection will have other injection methods, which will be explained in the following blogs. It is enough to understand the idea of ​​dependency injection.

// programming for the interface
public class Car{
    Iwheel whell;

    public Car(Iwhell whellA){ // Constructor dependency injection
        this.whell= whellA;
    }

    public Run(){
        whell.Run();
    }
}

Declarative programming based on aspects and conventions

Dependency injection keeps cooperating software components loosely coupled, while AOP programming allows you to separate out functionality from all over the application into reusable components. Which features are present throughout the app? For example, log functions, permission functions, etc., these functions are called aspect functions, because they cross each business module.

I believe many people have seen a situation where a business module is submerged in code that has nothing to do with business logic, such as logs, permission control, and transactions. Even if these functions are well packaged, the calling code is still embedded in the business logic code. . AOP not only well encapsulates common functions into components, but also prevents these common functions from being embedded in business logic code, making POJO simpler. How to make the aspect function code not intrude into the business code but realize the aspect function? Spring adopts the configuration method to configure the required aspect function where it is needed. Comparing the following two codes, you can clearly see that aspect programming makes POJOs very concise, focusing only on business logic and not on cut-in functions, which makes the coupling between aspect functions and business modules looser.

// Does not use AOP, relies on the log interface, and the log code invades the business logic
public class Car{
    Iwheel whell;
    ILog log;

    public Run(){
        log.info("before Run");
        whell.Run();
        log.info("after Run");
    }
}

// Using AOP, POJO does not know that there is a log at all, whether the log is needed and what kind of log to use to the user, POJO only cares about business logic
public class Car{
    Iwheel whell;

    public Run(){
        whell.Run();
    }
}

Reduce boilerplate code with aspects and templates

I believe that everyone has had this experience. When writing some code, it feels very similar to other code, such as database code, or remote call, or socket. First connect, then process the business, then close, and a series of repetitive codes such as catch exception, see the following example, the business code is overwhelmed by the boilerplate code.

Connection con = null;
        try {
            con = DriverManager.getConnection(dbUrl1, dbUserName, dbPassword);
            var stmt = con.prepareStatement("select * from users");   // only this line is the real business code
            var rs = stmt.executeQuery();
            System.out.println("Get database connection successfully!");
            System.out.println("Database operation!");
        } catch (SQLException e) {
            e.printStackTrace ();
            System.out.println("Failed to get database connection!");
        }finally{
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace ();
            }
        }
Spring aims to eliminate boilerplate code through template encapsulation. With jdbcTemplate, boilerplate code is eliminated, and only business logic needs to be concerned.
jdbcTemplate.queryForObject(
        "select * from users", // query statement
        new RowMapper<User>{} // result map
  )

Bean container

In spring, POJO only cares about its own business logic, not the creation and implementation of dependencies. Who is responsible for the creation of complex dependencies and who is responsible for the life cycle of dependencies, that is, the Bean container. The Bean container loads all beans (POJO class instances) and assembles complex beans by injecting beans.

 
 

Bean has a series of life cycle nodes in the container. Bean developers can define the hook function of the node to customize the bean, for example, when it is destroyed, some resources are released at the same time.

  • The establishment of Bean, the Bean definition file is read by BeanFactory, and each instance is generated
  • Setter injection, which performs property dependency injection of beans
  • BeanNameAware's setBeanName(), if this interface is implemented, its setBeanName method is executed
  • BeanFactoryAware's setBeanFactory(), if the interface is implemented, its setBeanFactory method is executed
  • The processBeforeInitialization() of BeanPostProcessor, if there is an associated processor, the processBeforeInitialization() method of this instance will be executed before the Bean is initialized
  • AfterPropertiesSet() of InitializingBean, if the interface is implemented, its afterPropertiesSet() method is executed
  • Define init-method in Bean definition file
  • processAfterInitialization() of BeanPostProcessors, if there is an associated processor, the processAfterInitialization() method of this instance will be executed before the Bean is initialized
  • DisposableBean's destroy(), when the container is closed, if the Bean class implements this interface, its destroy() method is executed
  • The destroy-method is defined in the bean definition file. When the container is closed, you can use the "destroy-method" defined in the bean definition file.

Spring modules

The Spring framework consists of several different modules, which provide everything needed to develop enterprise-level applications. The following is an overview of the modules. Each module will be introduced in detail in the following blogs. The function of the module is enough.


Summarize

The above is the summary of the first chapter of spring action, mainly to understand the goals of Spring and what means to achieve these goals. I believe you already have a general understanding of Spring. A follow-up blog will cover Spring in full detail.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325881546&siteId=291194637