WHY
At the beginning of its birth, the main purpose of creating Spring was to replace more heavyweight enterprise-level Java technologies, especially EJB. Compared to EJB, Spring provides a lighter and simpler programming model.
WHAT
Spring is an open source framework first created by RodJohnson. Spring was created to solve the complexity of enterprise-level application development. Using Spring can enable simple JavaBeans to implement things that only EJB could accomplish before. Spring is not limited to server-side development, any Java application can benefit from Spring in terms of simplicity, testability and loose coupling.
Today Spring is involved in mobile development, social API integration, NoSQL database, cloud computing and big data. Over time, EJB also adopted the concepts of dependency injection (DI) and Aspect-Oriented Programming (AOP). In short, Spring's most fundamental mission is to simplify Java development
HOW
In order to reduce the complexity of Java development, Spring adopts a 4-minute key strategy
Lightweight and minimal invasive programming based on POJO enables loose coupling through dependency injection and interface-oriented
Declarative programming based on sections and conventions reduces style code through sections and templates
POJO Potential
Many frameworks force applications to inherit their classes or implement their interfaces, which leads to applications being bound to the framework, which is invasive programming, resulting in the inability to reuse code blocks. Spring strives to avoid messing up your application code due to its own API. In applications built on Spring, its classes usually have no trace of any signs that you are using Spring.
public class HelloWorldBean { public String saysHello(){ return "Hello World"; }} The above example code represents a very simple and ordinary Java class (POJO). You can't tell that it is a Spring component. Spring's non-invasive programming is reflected in this class that can play a role in both Spring applications and non-Spring applications. Just this piece of code does not actually reflect Spring's functions, and the following knowledge is still needed.
Dependency injection (injecting the class itself dependent on)
Dependency injection is not so high in Spring, although it has evolved into a complex programming technique or design pattern concept. This is understood in Spring, injecting dependencies. An application with practical significance requires multiple classes to collaborate with each other to complete specific business logic. The traditional practice is that each object is responsible for managing references to objects related to itself (this related object is the object that is dependent on the object expressed in Spring), but this will make it difficult to test highly coupled and code.
Consider the following code
/**This difficult-to-mouthed class name was specially named by the author to fit a simulated scene* This class represents the knight who rescued the girl* Created by Wung on 2016/8/25. */public class DamselRescuingKnight implements Knight{private RescueDamselQuest quest;/** * Created RescueDamselQuest in its constructor * This makes DamselRescuingKnight and RescuingDamselQuest in its constructor coupled together*/public DamselRescuingKnight(){this.quest = new RescueDamselQuest();}public void embarkOnQuest(){quest.embark();}} Coupling has two sides. On the one hand, tightly coupled code is difficult to test, reuse and understand, and there will be "fighting the goblin" type bugs. On the other hand, a certain degree of coupling is necessary, and different classes must interact in an appropriate way.
The problem arises, so how did Spring solve it?
In Spring, through dependency injection (DI), the dependencies between objects are set by the third-party components in the system that coordinate each object when creating the object. In other words, objects only need to manage their internal properties without creating or managing their dependencies by themselves, and the dependencies will be automatically injected into the objects that need them.
/** * This knight can perform various adventure tasks instead of just the previous one to rescue the girl* Created by Wung on 2016/8/25. */public class BraveKnight implements Knight{private Quest quest;/** * BraveKnight does not create adventure types on its own, but passes adventure tasks as parameters during construction* This is one of the ways of dependency injection: constructor injection*/public BraveKnight(Quest quest){this.quest = quest;}public void embarkOnQuest(){quest.embark();}} BraveKnight is not coupled with any specific Quest implementation. As long as a task implements the Quest interface, it doesn't matter which type of adventure it is. This achieves the purpose of DI - loose coupling
If an object only indicates a dependency through an interface, then this dependency can be replaced with different concrete implementations without the object itself being aware of.
So now, let's inject practical meaning
For the above code, we will inject an adventure task with a specific implementation into the Brave Knight
/**The adventure mission of slaying dragons (this author is a good second-class) * Created by Wung on 2016/8/25. */public class SlayDragonQuest implements Quest{private PrintStream stream;public SlayDragonQuest(PrintStream stream){this.stream = stream;}public void embark() {stream.print("slay the dragon");}}So now the question is, how to inject the PrintStream object it depends on in SlayDragonQuest, how to inject the Quest object it depends on in BraveKnight. The aforementioned Spring will centrally manage these dependencies, and the behavior of creating collaboration between application components is usually called assembly (wiring), that is, injection. Spring provides a variety of assembly methods to introduce in more detail later. Here we briefly introduce the assembly based on XML and the assembly based on Java annotations.
<!-- This is an assembly process. Declare SlayDragonQuest as a bean, named "quest". Because it is a constructor injection, use the constructor-arg attribute value to represent the injected value. This process solves the previous problem. Inject the PrintStream object into the SlayDragonQuest object--> <bean id="quest"> <constructor-arg value="#{T(System).out}"> </constructor-arg></bean> <!-- This process is the same as above. BraveKnight declares a bean named "knight" (this name is not necessarily used) Then the constructor parameter of BraveKnight is required to be Quest type. At this time, another bean is passed in the reference, which is the reference of the bean with the name "quest" above. At this time, the constructor injection of BraveKnight is also completed-> <bean id="knight"> <constructor-arg ref="quest"> </constructor-arg></bean>Spring provides Java-based configurations that can be used as an alternative to XML
/**Java-based configuration file implements the assembly of objects* Created by Wung on 2016/8/26. */@Configurationpublic class KnightConfig { @Bean public Knight(){ return new BraveKnight(quest()); } @Bean public Quest quest(){ return new SlayDragonQuest(System.out); }}The effects are the same, and the specific explanation is described in detail in the next chapter. Let’s review it again. It has been said that Spring will automatically manage dependencies between objects, so what is this kind of manager? The answer is Application Context, which is a container for Spring that can load the definitions of beans and assemble them. Spring application context is solely responsible for the creation and assembly of objects. In fact, there are many ways to implement the difference between this Context, just the difference in loading configuration. Let’s see a way to load configuration.
public class KnightMain { public static void main(String[] args){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(KnightConfig.class); //The definition of the bean can be obtained from the configuration file. Knight knight = context.getBean(Knight.class); knight.embarkOnQuest(); context.close(); } }Apply face cutting
DI can keep collaborative software components loosely coupled, while facet programming allows you to separate functions all over the application to form reusable components, and, more specifically, it is a technology that drives software systems to strive for focus. What is a focus? System services such as logging, transaction management, and security management often need to be integrated into other components that have business logic themselves. These system services are usually called cross-cutting focus because they will be reused in multiple places, spanning multiple components of the system. Simply put, you extract the services that need to be reused from various other components, but how to use them? In fact, it is to insert the method into the places you need to use when using it. However, according to this term "section" it should be expressed as extracting the reused component as a section, and cutting the section through the component when needed. So in this way, core applications do not need to know the existence of these sections, and the sections will not integrate business logic into core applications.
/**A singer class is used to praise the knights, that is, to serve the knights* Created by Wung on 2016/8/26. */public class Minstrel { private PrintStream stream; public Minstrel(PrintStream stream){ this.stream = stream; } //Execute public void singBeforeQuest(){ stream.print("Begin"); } //Execute public void singAfterQuest(){ stream.print("End"); } } public class BraveKnight implements Knight{private Quest quest;private Minstrel minstrel;/** * BraveKnight does not create adventure types on its own, but passes adventure tasks as parameters in construction* This is one of the ways of dependency injection: constructor injection*/// public BraveKnight(Quest quest){// this.quest = quest;// }public BraveKnight(Quest quest, Minstrel minstrel){this.quest = quest;this.minstrel = minstrel;}public void embarkOnQuest(){minstrel.singBeforeQuest();quest.embark();minstrel.singAfterQuest();}} At this time, the brave knight began to execute, but he found that in his duties it was not just a risk, but now he had to manage the singer to praise him, but this itself should not belong to the category that should be managed. Therefore, using the idea of sections, we need to extract the singer's praise behavior and become a section. Before the Cavaliers take the risk, this section will be cut across and execute the singBeforeQuest method and execute the singAfterQuest method after the risk. So this will realize the code that does not need to be praised by the Knight, and the singer does not exist in the object of the Knight. He will not only praise the Knight, but also praise anyone as long as others use this section to enter.
<!-- means that configuring the bean with the above id as minstrel as a section is actually configuring the singer as a section --> aspect ref="minstrel"> <!-- Defining the entry point, that is, where to use the section expression="execution(* *.embarkOnQuest(..)) is an AspectJ point-cut expression language that will go deeper here. It means that the following is the embarkOnQuest() method, which is the pre-notice and post-note execution before and after the entry point-cut --> </aop:after></aop:before></aop:pointcut></aop:</aop:config>
The situation is that Minstrel is still an independent POJO, and the context of Spring has turned it into a section. The most important thing is that the knight has no idea of the existence of this section at this time. This is just a small chestnut, which can actually do many important things.
Use templates to eliminate style code
There is a situation where when we use JDBC to access the database to query data, the complete process requires establishing connections, creating statement objects, processing result sets, querying, and closing various connections. In addition, various exceptions are captured, and then queries in various scenarios require such painstaking repetition. JDBC is not just the only case where there is a lot of style code like this. Spring aims to eliminate style code through template encapsulation, such as Spring's jdbcTemplate.
Accommodate your bean
In Spring-based applications, your application objects live in Spring containers, which are responsible for creating objects assembled objects and managing their life cycles. So what is Spring container? There is not only one type of container. Spring comes with multiple container implementations. It is divided into two categories: bean factories, which are the simplest containers to provide basic DI support. The application context is relatively advanced and provides application framework-level services. Most of the time, application context is more popular.
The application context is also divided into many different ways of loading configurations.
Various Spring features
Summarize
Spring is a framework technology that can simplify development, and its core content is DI and AOP.
The above is the gossip about this article - gradually understand Spring's entire content, I hope it will be helpful to everyone. Interested friends can continue to refer to this site:
SpringMVC Getting Started Example
Detailed explanation of the code for injecting attribute value using configuration files and @value in Spring
Spring Integrated Redis Detailed Code Sample
If there are any shortcomings, please leave a message to point it out.