Spring: Confusion over the Right Learning Path

In the last few days, I taught myself Spring Boot and created a server and client for the REST web service, then added basic authentication and deployed both a standalone and a military package. I did this by including spring-boot-starter-web , spring-boot-starter-test , spring-boot-starter , spring-boot-starter-security , spring-boot-starter-tomcat , spring-web in the gradle project jackson-databind and by copying hten using various websites.

After confusing with many websites that do things very differently (completely different annotations, some use configuration files), it worked, and then I modified it using an interceptor / message converter, the original headers, and then through the leisure builder template .

However, I feel like I really don’t know how and why it worked, although I wrote a fair bit of code to make it all work, including basic authentication, in four different ways. It just magically worked, and I don't like it: for example, if I wanted to add more things that were not “loaded”, how would I do it, or everything that annotations do, and why they are needed, for example @SpringBootApplication , @Configuration or why some classes @Bean and others not).

To shorten the long story, Spring is a massive structure (a site containing a list of packages takes over the page), should I really learn Spring core / framework first, and then maybe Spring MVC or Spring before starting the download?

I can find many resources for teaching me various packages, but none of them tell me why they work or where to really start, and specifically will not tell me how the packages interact. This is pretty overwhelming.

I expect this to be closed as not being constructive, but seems to be the best place to respond to Spring.

+5
source share
2 answers

A very short history of Spring

Let's start with a little history lesson ... In 2002, most Java developers worked in the J2EE space, and many of them were unhappy. One of them was Rod Johnson, who wrote a book called J2EE Design and Development , One-on-One Expert , and that was how it was possible to develop a corporate application without EJB and better. The code for this book became the foundation of the Spring Framework.

Spring Configuration

Let's look at a simple Java class.

 @Component("hello") public class HelloWorld { private String name = "World!"; public void setName(String name) { this.name=name; } public void sayHello() { System.out.println("Hello, " + name); } } 

Spring Configuration - Property Files

At first, the only configuration option was to use the properties file. Let's call this file application-context.properties . To create an instance of the java class above and set the name, the following content is needed in application-context.properties .

 hello.(class)=biz.deinum.samples.configurations.HelloWorld hello.name=Marten! 

(class) was a special property (more similar to (scope) and (abstract) see javadoc for more. This indicates which class needs to be loaded to load. To use the properties file, you would need to create a PropertiesBeanDefinitionReader to pass that BeanFactory . (Which, in turn, ApplicationContext can be passed if you need fancy features like AOP)

 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions("classpath:application-context.properties"); HelloWorld helloWorld = beanFactory.getBean("hello", HelloWorld.class); helloWorld.sayHello(); 

However, this property-based configuration was a bit limited, and XML matched the world. Therefore, the first steps in the XML configuration where you are born.

Spring Configuration - XML ​​Files (Part 1)

To present the same configuration with XML, the following is required.

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="hello" class="biz.deinum.samples.configurations.HelloWorld"> <property name="name" value="Marten!" /> </bean> </beans> 

On boot, this will create a HelloWorld instance with the same settings as the properties file. To download it, XmlBeanDefinitionReader will need XmlBeanDefinitionReader .

 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions("classpath:/applicationContext-basic.xml"); HelloWorld helloWorld = beanFactory.getBean("hello", HelloWorld.class); helloWorld.sayHello(); 

Spring Configuration - XML ​​Files (Part 2)

XML is pretty verbose but readable. But setting up things like AOP (like transactions), MVC, etc. is pretty time consuming. (Or things like security, see this for the predecessor of Spring Security without a namespace). Thus, the new and improved XML had the concept of namespaces allowing things like <tx:annotation-driven /> <aop:config /> , etc.

Spring Configuration - Driven Annotation

The next step was the introduction of Java5, which enabled annotations. Since the entire Java community requested annotation-based customization, this was added. Hence the introduction of @Component , @Autowired and the like.

Adding @Component to the HelloWorld class and using the namespace to enable component scanning reduces the amount of XML that needs to be written.

Assuming @Component("hello") is in the HelloWorld class, the following XML is required.

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="biz.deinum.samples.configurations" /> </beans> 

To download this configuration, simply change the location of the downloaded file.

Spring Configuration - Java Configuration

Then suddenly the love of XML ended, and people wanted to use a language that they know, and that language is Java. Consequently, the birth of a Java-based configuration.

 @Configuration public class HelloWorldConfiguration { @Bean public HelloWorld hello() { HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Marten!"); return helloWorld; } } 

The @Bean is a sign that this method creates a bean and is processed using ASM before the actual Spring boot. However, Java Config processing is quite complex and only works with ApplicationContext . You can add the @Configuration class to the xml file and load it for processing, or use the specialized AnnotationConfigApplicationContext to load (or detect).

 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class); context.getBean("hello", HelloWorld.class).sayHello(); 

In XML, we have namespaces to simplify the configuration. In the Java Config environment, we have various @Enable* annotations, such as @EnableTransactionManagement , which is the same as <tx:annotation-driven /> in XML.

Thoughts / Suggestions

Which configuration option to use if you are new, I suggest starting with a Java based configuration, although XML is probably a little easier to understand (IMHO). All configuration options still work today, you can even mix and match them if necessary.

For Spring it does not matter, for Spring it matters BeanDefinition , the source of which is used to create them (properties, xml or java configuration) does not matter.

Spring Download

So far, the only thing that has been covered is Spring. No other project has been affected (although mentioned). But, as you can imagine, time goes on, and as the configuration grows and the complexity of the applications we want more agreement on the configuration . One of the reasons Spring Boot saw the light.

Labeling a class with @SpringBootApplication does this a @Configuration class, enables component scanning (starting from the same package that contains the annotated class) and enables automatic tuning.

 @SpringBootApplication public class HelloApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(HelloApplication.class, args); BeanFactoryHelper.sayHello(context); BeanFactoryHelper.statistics(context); } @Bean public HelloWorld hello() { HelloWorld hello = new HelloWorld(); hello.setName("Marten!"); return hello; } } 

This class will launch the application, say hello, print some information about the context and the end. Without creating an application context or factory yourself.

Why is the @Bean method well, the HelloWorld class is in a package that is not covered by the standard scan of Spring Boot components and therefore we need to declare a bean. We can do this in the HelloApplication class because it is also @Configuration (due to the fact that this is a meta annotation on @SpringBootApplication ).

Now, if you replace @SpringBootApplication with @SpringBootApplication(scanBasePackageClasses = HelloWorld.class) , you can remove the @Bean annotation because HelloWorld will now be detected when scanning components (activated by @ComponentScan meta-annotation with @SpringBootApplication ).

The code for this answer can be found here .

+4
source

Spring is based on importing dependencies and is used for REST web services, but this does not mean that you cannot have Spring in any base application.

To shorten the long story, Spring is a massive structure (a site containing a list of packages takes over the page), should I really study Spring core / framework before anything else, and then maybe Spring MVC or Spring web services before downloading?

You should learn how Spring works and how instances work. It basically searches in your project and creates an instance of each class annotated with @Component ( @Service , @RestController , @Controller ... etc.). When you are @Autowire , your variable is passed.

After confusing with many websites that do things very differently (completely different annotations, some use configuration files), it worked, and then I modified it using an interceptor / message converter, the original headers, and then through the leisure builder template .

Most of the examples that you can find on the Internet over 1-2 years old are probably outdated (but not always). When you are looking for something, keep that in mind. This is the main reason why there are so many implementations.

I can find many resources for teaching me various packages, but none of them tell me why they work or where to really start, and specifically will not tell me how the packages interact. This is pretty overwhelming.

This is amazing. This is a large structure with a large area of ​​applicability. The best place to find out how everything works: https://spring.io/docs/reference

+2
source

Source: https://habr.com/ru/post/1262890/


All Articles