The most comprehensive Spring learning notes and spring learning notes

Source: Internet
Author: User

The most comprehensive Spring learning notes and spring learning notes

Spring is committed to providing a way to manage your business objects. Spring can be seen everywhere in a large number of Java EE applications. Today, I will briefly introduce the Spring framework.

This article is suitable for readers:

  • Java developers who want to learn Spring
  • People who have just used Spring
Why

Why use Spring?

Spring provides two convenient methods for managing business objects:

  • DI (Dependency Injection, Dependency Injection)
  • AOP (Aspect Oriented Programming, Aspect-Oriented Programming)
Java Bean

Every class can be taken over by Spring only when Bean specifications are implemented. What are Bean specifications?

  • Must be a public class
  • Parameter Constructors
  • Expose internal Member attributes (getter, setter) using public methods)

Classes that implement such a specification are called Java Beans. It is a reusable component.

DI-dependency Injection

Simply put, a system may have thousands of objects. It is unthinkable to manually maintain the relationships between them. We can describe the relationship between them in Spring XML files, and Spring will automatically inject them. For example, Class A instances need class B instances as the parameter set.

AOP-Aspect-Oriented Programming

Take the log system as an example. Logs must be output before and after an operation is executed. If you manually add code, it is terrible. In addition, when the code is large, it is also very difficult to maintain. This requires Aspect-Oriented Programming.

How about BeanBean Lifecycle

As you can see, the bean factory has performed several startup steps before bean is ready. We will describe the graph in detail:

Bean Scope

Spring defines various Bean scopes and can create beans based on these scopes, including:

  • Singleton: Only one bean instance is created throughout the application.
  • Prototype: A new bean instance is created every time a Prototype is injected or obtained through the Spring application context.
  • Session: Creates a bean instance for each Session in a Web application.
  • Request (Rquest): Creates a bean instance for each request in a Web application.

The code looks like this:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public class MyIsBean{...}

XML version:

<bean id="BEANID"  class = "net.itxm.beans"  scope="prototype">

By default, all beans in the Spring application context are created as singleton instances. That is to say, no matter how many times a given bean is injected into other beans, each injection is the same instance.

In most cases, Singleton bean is an ideal solution. The cost of initialization and garbage collection object instances is only reserved for some small-scale tasks. In these tasks, it may not be reasonable to keep the objects stateless and reuse these objects repeatedly in the application.

Sometimes, you may find that the classes you use are mutable, and they maintain some status, so reuse is not safe. In this case, it is not a good idea to declare the bean class as a Singleton, because the object will be contaminated and unexpected problems will occur when it is reused later.

Declare Bean

The annotation for Bean declaration is as follows:

  • @ Component, no clear role
  • @ Service used in the business logic layer
  • @ Repository
  • @ Controller used in the presentation layer (MVC-> Spring MVC)
  • Here, you can specify the bean id: Component ("yourBeanName ")
  • Spring also supports @ Named as an alternative to @ Component annotations. There are some minor differences between the two, but they can be replaced in most scenarios.
Annotation of dependency injection Bean @ Autowired Spring

It is not only an object, but also a constructor. It can also be used in the Setter method of the attribute.

Spring tries to satisfy the dependencies declared on method parameters, whether it is the constructor, Setter method, or other methods. If there is only one bean matching the dependency requirement, the bean will be assembled.

If no matching bean exists, Spring will throw an exception when the application context is created. To avoid exceptions, set the required attribute of @ Autowired to false.

When the required attribute is set to false, Spring will try to execute automatic assembly. However, if no matching bean exists, Spring will put the bean in the unassembled state. However, you must be cautious when setting the required attribute to false. If no null check is performed in your code, NullPointerException may occur for this unassembled property.

@ Inject annotation comes from the Java dependency injection specification, which also defines @ Named annotation for us. In automatic assembly, Spring supports both @ Inject and @ Autowired. Although there are some minor differences between @ Inject and @ Autowired, they can be replaced in most scenarios.

@Autowired Is one of the most common annotations, but in the old project, you may see these annotations, their functions and@Autowired Similar:

  • @InjectIs the annotation provided by the JSR-330
  • @ResourceIs the annotation provided by the JSR-250
Conditional Bean

Suppose you want one or more beans to be created only when the application's class path contains a specific library. Or we want a bean to be created only when another specific bean is declared. We may also require that a bean be created only after a specific environment variable is set.

Before Spring 4, it was difficult to implement conditional configuration at this level, but Spring 4 introduced a new@ConditionalAnnotation, which can be used with @ Bean annotation. If the given condition calculation result is true, the bean will be created. Otherwise, the bean will be ignored.

Through ConditionContext, we can do the following:

  • Use the BeanDefinitionRegistry returned by getRegistry () to check bean definitions;
  • Use the ConfigurableListableBeanFactory () returned by getBeanFactory to check whether the bean exists or even explore bean attributes;
  • Use the Environment returned by getEnvironment () to check whether the Environment variable exists and its value;
  • Read and explore the resources loaded by the ResourceLoader returned by getResourceLoader;
  • Use the ClassLoader returned by getClassLoader () to load and check whether the class exists.
Processing automatically assembled ambiguity labels preferred bean

When declaring a bean, you can set an optional bean as the primary bean to avoid ambiguity during automatic assembly. In case of ambiguity, Spring will use the preferred bean instead of other optional beans. In fact, what you declare is the "favorite" bean.

Limits automatically assembled beans

The limitation of setting the preferred bean is that @ Primary cannot limit the range of the optional scheme to the only unambiguous option. It can only indicate one priority option. When the number of preferred beans exceeds one, there is no other method to further narrow down the optional range.

In contrast, Spring's qualifier can narrow the scope of all optional beans, and eventually only one bean can meet the specified restriction conditions. If there is still ambiguity after all the qualifiers are used, you can continue to use more qualifiers to narrow the selection range.

@ Qualifier annotation is the main method to use a Qualifier. It can be used together with @ Autowired and @ Inject to specify the bean to be injected during injection. For example, we want to ensure that IceCream is injected into setDessert:

@Autowired@Qualifier("iceCream")public void setDessert(Dessert dessert){  this.dessert = dessert;}

This is the simplest example of using a qualifier. The parameter set for @ Qualifier annotation is the ID of the bean to be injected. All classes declared using the @ Component annotation are created as beans, and the bean ID becomes a lower-case class name. Therefore, @ Qualifier ("iceCream") points to the bean created during component scanning, and this bean is an instance of the IceCream class.

In fact, there is another point to add. More accurately, the bean referenced by @ Qualifier ("iceCream") must have the "iceCream" of the String type as the Qualifier. If no other qualifier is specified, all beans are given a default qualifier, which is the same as the bean ID. Therefore, the Framework injects the bean with the "iceCream" qualifier into the setDessert () method. This happens to be the bean whose ID is iceCream. It was created by the IceCream class during component scanning.

Using the default bean ID as a qualifier is very simple, but this may introduce some problems. If you reconstruct the IceCream class and rename it as Gelato, What will happen now? In this case, the bean ID and default qualifier will change to gelato, which cannot match the qualifier in setDessert () method. Automatic Assembly fails.

The problem here is that the qualifier specified on the setDessert () method is tightly coupled with the name of the bean to be injected. Any change to the class name will invalidate the qualifier.

SpringEL
  • Value to inject resources
Bean initialization and destruction
  • Java configuration method: initMethod and destoryMethod
  • Annotation: @ PostConstruct and @ PreDestory
Profile

Different configurations are available in different environments.

Activate Profile

Spring depends on two independent attributes when determining which profile is active: spring. profiles. active and spring. profiles. default. If the spring. profiles. active attribute is set, its value is used to determine which profile is activated. However, if the spring. profiles. active attribute is not set, Spring will look for the value of spring. profiles. default. If neither spring. profiles. active nor spring. profiles. default is set, no activated profile is available. Therefore, only beans not defined in the profile are created.

Use profile for testing

When you run an integration test, you usually want to use the same configuration as the production environment (or a subset of the production environment) for testing. However, if the bean in the configuration is defined in the profile, we need to enable the appropriate profile when running the test.

Spring provides the @ ActiveProfiles annotation, which can be used to specify the profile to be activated during the test. During integration testing, the profile of the development environment is usually to be activated.

For example, Profile ("dev ")

Application Event

UseApplication EventBean and Bean communication can be achieved

Spring events must follow the following process:

  • Integrate ApplicationEvent with custom events
  • Define Event Listeners and implement ApplicationListener
  • Use container to publish events
Advice)

The notification defines what the aspect is and when to use it. In addition to describing the work to be completed, the notification also solves the problem of when to execute the work. Should it be applied before a method is called? After? Call both before and after? Or is it called only when a method throws an exception?

Five types of notifications can be applied to the Spring aspect:

  • Before: Call the notification function Before the target method is called;
  • Post-notification (After): Call the notification After the target method is completed. At this time, you do not care about the output of the method;
  • After-returning: Call the notification After the target method is successfully executed;
  • After-throwing: Call the notification After the target method throws an exception;
  • Surround notification: the notification wraps the method to be notified and performs custom actions before and after the method to be notified is called.

Corresponding Annotations:

Note Notice
@ After The notification method is called after the target method returns or throws an exception.
@ AfterReturning The notification method will be called after the target method returns
@ AfterThrowing The notification method is called after the target method throws an exception.
@ Around The notification method encapsulates the target method.
@ Before The notification method is executed before the target method is called.
Join point)

A connection point is a point that can insert a plane surface during application execution. This can be when a method is called, an exception is thrown, or even a field is modified. The aspect code can use these points to insert them into the normal process of the application and add new behaviors.

Pointcut)

If the notification defines "what" and "when", the cut point defines "where ". The definition of the cut point matches one or more connection points to be woven into the notification. We usually use clear class and method names, or use regular expressions to define matched classes and method names to specify these cut points. Some AOP frameworks allow us to create dynamic cut points and decide whether to apply notifications Based on runtime decisions (such as method parameter values.

Aspect (Aspect)

Notification + cut point = cut surface

Introduction (Introduction)

Introduction allows us to add new methods or attributes to existing classes

Weaving)

Weaving is the process of applying a plane to the target object and creating a new proxy object. The section is woven into the target object at the specified connection point. In the lifecycle of the target object, multiple points can be woven:

  • Compilation phase: the aspect is woven into the target class during compilation. This method requires a special compiler. The weaving compiler of AspectJ is to weave the plane surface in this way.
  • Class loading period: the plane is woven when the target class is loaded to JVM. This method requires a special ClassLoader, which can enhance the bytecode of the target class before the target class is introduced into the application. Load-time weaving (LTW) of AspectJ 5 supports this method.
  • Runtime: the slice is woven into the application at a certain time point during running. Generally, when the plane is woven, the AOP container dynamically creates a proxy object for the target object. Spring AOP is woven into the plane in this way.
Spring's support for AOP:

The first three are variants of Spring AOP implementation. Spring AOP is built on the basis of dynamic proxy. Therefore, Spring's support for AOP is limited to method interception. That is to say, AspectJ is king.

In addition, Spring wraps the section into the bean managed by Spring during runtime. As shown in, the proxy class encapsulates the target class, blocks calls to the notified method, and forwards the call to the real target bean. When a method call is intercepted, the method logic is executed before the target bean method is called. Spring does not create a proxy object until the bean of the application needs to be proxy. If ApplicationContext is used, Spring will create the proxy object only when ApplicationContext loads all beans from BeanFactory. Because proxy objects are created during Spring runtime, we do not need a special compiler to weave the aspect of Spring AOP.

Example
public interface Performance(){  public void perform();}

Write a cut-point expression that can set the call to trigger the notification when the perform () method is executed.

Execution (* concert. performance. perform (..)) // execution: triggered when the method is executed // *: returns any type // concert. performance: method class // perform: method name //(..): Use any parameter

Not only that, but it is more complicated to write.

Execution (* concert. performance. perform (..) & within (concert. *) // added an operation. This operation is triggered when any class method under the concert package is called.

Select bean from the cut point

Execution (* concert. Performance. perform () and bean ('woodstock') // specify the bean id as woodstock.

To make a complete cut

@Aspectpublic class Audience{  @Before("execution(**concert.Performance.perform(..))")  public void silenceCellPhones(){    System.out.println("Silencing cell phones");  }  @Before("execution{** concert.Performance.perform{..}}")  public void taskSeats(){    System.out.println("Talking seats");  }  @AfterReturning("execution{** concert.Performance.perform{..}}")  public void applause(){    System.out.println("CLAP CLAP CLAP!!!");  }  @AfterThrowing("execution{** concert.Performance.perform{..}}")  public void demanRefund(){    System.out.println("Demanding a refund");  }}

It can be simplified.

@ Aspectpublic class Audience {// avoid frequent use of the cut point expression @ Pointcut ("execution (** concert. performance. perform (..)) ") public void performance () {}@ Before (" performance () ") public void silenceCellPhones () {System. out. println ("Silencing cell phones") ;}@ Before ("performance ()") public void taskSeats () {System. out. println ("Talking seats") ;}@ AfterReturning ("performance ()") public void applause () {System. out. println ( "CLAP !!! ") ;}@ AfterThrowing (" performance () ") public void demanRefund () {System. out. println (" demaning a refund ");}}
Statement section in XML
AOP configuration element Purpose
<Aop: advisor> Define the AOP notifier
<Aop: after> Define post-notification for AOP (no matter whether the notified method is successfully executed)
<Aop: after-returning> Define AOP return notification
<Aop: after-throwing> Define AOP exception notifications
<Aop: around> Define AOP surround notification
<Aop: aspect> Define a plane
<Aop: aspectj-autoproxy> Enable @ AspectJ annotation-driven cut plane
<Aop: before> Define an AOP pre-notification
<Aop: config> The top-layer AOP configuration element. Most <aop: *> elements must be included in <aop: config> elements.
<Aop: declare-parents> Introduce additional interfaces for notification objects in a transparent manner
<Aop: pointcut> Define a cut point

Here is a chestnut.

public class Audience{  public void silenceCellPhones(){    System.out.println("Silencing cell phones");  }  public void taskSeats(){    System.out.println("Talking seats");  }  public void applause(){    System.out.println("CLAP CLAP CLAP!!!");  }  public void demandRefund(){    System.out.println("Demanding a refund");  }}

Declare the unannotated Audience as a cut surface using XML

<aop:config>  <aop:aspect ref="audience">    <aop:before      pointcut ="execution(** concert.Performance.perform(..))"      method="sillenceCellPhones"/>    <aop:before      pointcut ="execution(** concert.Performance.perform(..))"      method="taskSeats"/>    <aop:after-returning      pointcut ="execution(** concert.Performance.perform(..))"      method="applause"/>    <aop:After-throwing        pointcut ="execution(** concert.Performance.perform(..))"        method="demanRefund"/>  </aop:aspect></aop:config>

The most important aspect of AspectJ's AspectJ cut point in Spring AOP is that Spring only supports a subset of AspectJ Cut Point Indicators (pointcut designator. Let's review that Spring is proxy-based, and some cut-point expressions are irrelevant to Agent-Based AOP. The following table lists the AspectJ point switches supported by Spring AOP.

Spring uses AspectJ's cut point Expression Language to define Spring aspect

AspectJ indicator Description
Arg () Specifies the method of executing the connection point matching parameter.
@ Args () Execution Method for specifying annotation to restrict Connection Point Matching Parameters
Execution () Execution Method for matching a connection point
This () Restrict the connection point to match the bean reference of the AOP agent to a class of the specified type
Target Restrict the connection point to match the target object to a class of the specified type
@ Target () Restrict connection points to match specific execution objects. The classes corresponding to these objects must have annotation of the specified type.
Within () Restrict the specified type of connection point matching
@ () Restrict connection points to match the types marked by the specified annotation (when Spring AOP is used, the method is defined in the class marked by the specified annotation)
@ Annotation Restrict the connection points that match the specified Annotation
Advanced Spring features

Due to Spring's special dependency injection technique, there is no coupling between beans.

However, beans sometimes need to use the resources of the spring container. In this case, your Bean must be aware of the existence of the Spring container. So we need to use Spring Aware. Let's take a look at the interfaces provided by Spring Aware.

BeanNameAware Obtain the Bean name in the container.
BeanFactory Obtain the current bean factory, so that the container service can be called.
ApplicationContextAware * Current application context, which can call the Container Service
MessageSourceAware Get Message source
ApplicationEventPublisherAware Application Time publisher, which can be released,
ResourceLoaderAware Obtain the resource loader to obtain external resource files
@ TaskExecutor

In this way, multithreading and concurrent programming can be implemented. Enable support for asynchronous tasks through @ EnableAsync, and declare it as an asynchronous task by using @ Async annotation in the actual Bean method.

@ Scheduled task

First, enable support for Scheduled tasks by configuring class annotation @ EnableScheduling, and then annotate @ Scheduled on the method for executing the Scheduled task to declare that this is a Scheduled task.

@ Conditional

Create a specific Bean according to a specific condition.

Combination annotation and meta Annotation

Meta annotation is the annotation that can be annotated to other annotations. The annotation is called a combination annotation, and the combination annotation has the annotation function.

@ Enable * annotation Working Principle

By observing the source code of these @ Enable * annotations, we find that all annotations have a @ Import annotation, which is used to Import the configuration class, this is surprising that these automatically enabled implementations actually import some automatically configured beans. The following three methods are used to import configurations:

  • Category 1: Direct import Configuration
  • Category 2: Select Configuration classes based on conditions
  • Category 3: dynamically register beans
What

Briefly analyze Spring.

There are only three Core components in the Spring framework: Core, Context, and Bean. They build the entire Spring skeleton architecture. Without them, it is impossible to have top-layer features such as AOP and Web. The following will also analyze Spring from these three components.

Spring Design Concept

Those who have used Spring know that Bean plays an important role in Spring. A series of simple configurations are used to satisfy the dependency between classes. This is called dependency injection. The dependency injection relationship is managed in a container named IOC.

Core Components

We have mentioned that there are only three Core components in the Spring framework: Core, Context, and Bean. So how does Core and Context work together?

We know that beans wrap objects, and objects must have data. How to provide a living environment for these data is a problem to be solved by Context, for Context, it is necessary to discover the relationship between each Bean, establish this relationship for them, and maintain this relationship. Therefore, Context is a collection of Bean relations, which is also called the Ioc container. Spring can work for you once this Ioc container is created. What is the use of Core components? In fact, Core is a tool for discovering, establishing, and maintaining the relationship between each Bean.

Parse Core Component Bean

We have explained the importance of Bean components to Spring. Let's look at how to design Bean components. The Bean component is in the org. springframework. beans package of Spring. All classes in this package mainly solve three things: Bean definition, Bean creation, and Bean parsing. The only concern for Spring users is Bean creation. The other two are completed by Spring internally, which is transparent to you.

The typical factory mode when Spring Bean is created. Its top-level interface is BeanFactory, which is the inheritance hierarchy of the factory:

BeanFactory has three subclasses: ListableBeanFactory, HierarchicalBeanFactory, and AutowireCapableBeanFactory. However, we can find that the final default implementation class is DefaultListableBeanFactory, which implements all interfaces. So why do we need to define such a multi-level interface? Check the source code and description of these interfaces and find that each interface has its own application. It is mainly used to differentiate the object transfer and conversion process in the Spring internal operation process, restrictions on object data access. For example, the ListableBeanFactory interface indicates that these beans can be listed, while HierarchicalBeanFactory indicates that these beans are inherited, that is, each Bean may have a parent Bean. The AutowireCapableBeanFactory interface defines automatic Bean Assembly rules. These four interfaces jointly define the Bean set, the relationship between beans, and Bean behavior.

Context

ApplicationContext is the top-level parent class of Context. It not only identifies the basic information of an application environment, but also inherits five interfaces. These five interfaces mainly extend the Context function. The class structure of Context is as follows:

We can see thatApplicationContextBeanFactory is inherited, which also indicates that the main object running in the Spring container is Bean.ApplicationContextInherits the ResourceLoader interfaceApplicationContextYou can access any external resources, which will be detailed in Core.

ApplicationContextThe subclass includes two main aspects:

  • ConfigurableApplicationContextIt indicates that the Context is changeable, that is, you can dynamically add or modify the existing configuration information in the build Context. There are multiple sub-classes under it, among them, the most frequently used is the updatable Context, that isAbstractRefreshableApplicationContextClass.
  • WebApplicationContextAs the name suggests, it means that the Context prepared for the web can directly access ServletContext. In general, this interface is rarely used.

The next step is to construct the Context file type, followed by accessing the Context. In this way, the level 1 constitutes a complete level of Context.

In general, ApplicationContext must do the following:

  • Identifies an application environment
  • Use BeanFactory to create Bean objects
  • Save object relationship table
  • Ability to capture various events

As the IOC container of Spring, Context basically integrates most of Spring functions, or is the basis of most functions.

Core

As the Core component of Spring, the Core component contains many key classes. An important component is to define the resource access method. This method of abstracting all resources into an interface is worth learning in future design. Next, let's take a look at the role of this part in Spring.

It can be seen that the Resource interface encapsulates various possible Resource types, that is, it shields users from different file types. For the Resource provider, how to package the Resource and hand it over to others is also a problem. We can see that the Resource interface inheritsInputStreamSourceInterface, which has a getInputStream method and returns the InputStream class. In this way, all resources can be obtained through the InputStream class, and thus the resource provider is blocked. Another problem is the loading of resources, that is, the resource loaders should be unified. It can be seen that this task is completed by the ResourceLoader interface, it shields the differences between all resource loaders. You only need to implement this interface to load all resources. Its default implementation isDefaultResourceLoader.

So how does Context and Resource establish a relationship?

It can be seen that Context delegates resource loading, parsing, and description to the ResourcePatternResolver class, which is equivalent to a connector, it integrates resource loading, parsing, and resource definition to facilitate the use of other components. There are many similar methods in Core components.

Summary

This article is a collection of notes from previous Spring studies. If you have any errors or questions, please leave a message to me. This is an opportunity for us to learn and make progress together.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.