过去几天我一直在教自己Spring Boot并创建了一个REST Web服务服务器和客户端,然后添加了基本身份验证,并作为独立和war包部署。我通过在我的gradle项目中合并spring-boot-starter-web
,spring-boot-starter-test
,spring-boot-starter
,spring-boot-starter-security
,spring-boot-starter-tomcat
,spring-web
,jackson-databind
来做到这一点并通过各种网站进行复制。
在众多网站以完全不同的方式处理事情(完全不同的注释,一些配置文件的使用)之后,它工作了,然后我使用拦截器/消息转换器,原始标头然后通过休息模板修改它助洗剂。
但是,我觉得我真的不知道它是如何工作的,为什么它有效呢,尽管我用4种不同的方式编写了一些代码来完成所有工作,包括基本身份验证。它只是神奇地工作,我不喜欢它:例如,如果我想添加更多不是“启动”的东西,我将如何做,或者所有注释都在做什么以及为什么需要它们,例如@SpringBootApplication
,@Configuration
或为什么某些课程@Bean
而其他课程没有。{/ p>
简而言之,spring是一个庞大的框架(列出软件包的网站单独占用一个页面),我应该先学习spring core / framework之前的其他东西,那么可能是spring MVC或spring web services在学习启动之前?
我可以找到许多资源来教我不同的软件包,但没有一个可以告诉我它们为什么工作或者从哪里开始,特别是没有什么能告诉我这些软件包是如何相互链接的。这是非常压倒性的。
我希望这会被关闭而不是建设性的,但它似乎是获得Spring答案的最佳位置。
答案 0 :(得分:5)
让我们从一个历史课开始......这一年是2002年,大多数Java开发人员都在J2EE领域工作,其中很多人都不高兴。其中一个是Rod Johnson,他写了一本名为Expert One-on-One J2EE Design and Development的书,它是如何在没有EJB和更好的方式的情况下开发企业应用程序的。本书的代码成为Spring Framework的基础。
让我们看看一个简单的Java类。
@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);
}
}
一开始,唯一的配置选项是使用属性文件。让我们将此文件命名为application-context.properties
。要创建上面java类的实例并设置名称,需要application-context.properties
中的以下内容。
hello.(class)=biz.deinum.samples.configurations.HelloWorld
hello.name=Marten!
(class)
是一个特殊属性(更像是(scope)
和(abstract)
,请参阅javadoc了解更多选项。这表明需要加载哪个类要使用属性文件,必须创建一个BeanFactory
传递ApplicationContext
。(如果您需要像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();
<?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>
然而,基于属性的配置有点限制,XML正在向全世界表示赞同。因此,出生的XML配置的第一步。
要用XML表示相同的配置,需要以下内容。
HelloWorld
加载时,这将创建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();
。
<tx:annotation-driven />
XML非常冗长但可读。但是配置诸如AOP(例如事务),MVC等之类的东西是相当费力的。 (或者安全性,请参阅PropertiesBeanDefinitionReader
,了解没有命名空间的Spring Security的前身)。因此,新的和改进的XML具有名称空间的概念,允许<aop:config />
@Component
等等。
下一步是引入Java5,允许注释。随着整个Java社区要求基于注释的配置,这被添加。因此引入了@Autowired
,@Component
等。
将HelloWorld
添加到@Component("hello")
类并使用命名空间来启用组件扫描可以减少必须编写的XML数量。
假设HelloWorld
类上有<?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>
,则需要以下XML。
@Configuration
public class HelloWorldConfiguration {
@Bean
public HelloWorld hello() {
HelloWorld helloWorld = new HelloWorld();
helloWorld.setName("Marten!");
return helloWorld;
}
}
要加载此配置,只需更改要加载的文件的位置即可。
然后突然之间对XML的热爱已经结束,人们想要使用他们所知道的语言,而语言就是Java。因此诞生了基于Java的配置。
@Bean
ApplicationContext
注释表示此方法生成bean并在Spring实际加载之前使用ASM进行处理。但是,Java Config处理非常复杂,仅适用于@Configuration
。您可以将AnnotationConfigApplicationContext
类添加到xml文件中并加载它以使其处理或使用专门的AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
context.getBean("hello", HelloWorld.class).sayHello();
来加载(或检测)它。
@Enable*
在XML中,我们有用于简化配置的命名空间。在Java Config中,我们有@EnableTransactionManagement
个注释,如<tx:annotation-driven />
,与XML中的BeanDefinition
相同。
使用哪个配置选项,如果你是新手,我建议从基于Java的配置开始,尽管XML可能更容易理解(恕我直言)。所有配置选项今天仍然有效,如果需要,您甚至可以混合搭配。
对于Spring来说,无关紧要,对于Spring来说最重要的是@SpringBootApplication
哪个源用于构造它们(属性,xml或java配置)并不重要。
到目前为止,唯一涵盖的是Spring本身。没有其他项目被触及(虽然已经提到)。但随着时间的推移,随着配置和应用程序复杂性的增长,我们想要更多this。 Spring Boot看到光明的原因之一。
使用@Configuration
标记类使该类成为@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;
}
}
,将启用组件扫描(从带注释的类所在的同一个包开始)并启用自动配置。
@Bean
这个类将启动应用程序,打个招呼,在上下文中打印一些信息并结束。没有您自己创建应用程序上下文或工厂。
为什么HelloWorld
类和HelloApplication
类都在Spring Boot的默认组件扫描未涵盖的包中,因此我们需要声明bean。我们可以在@Configuration
类中执行此操作,因为它也是@SpringBootApplication
(因为它是@SpringBootApplication
上的元注释)。
现在,如果您将@SpringBootApplication(scanBasePackageClasses = HelloWorld.class)
替换为@Bean
,则可以删除HelloWorld
注释,因为现在可以通过组件扫描检测到@ComponentScan
(由{{1}启用@SpringBootApplication
)上的元注释。
可以找到此答案的代码convention over configuration。
答案 1 :(得分:2)
Spring框架是关于依赖注入的,它用于REST Web服务,但这并不意味着你不能在任何基本应用程序中使用Spring。
简而言之,spring是一个庞大的框架(列出软件包的网站单独占用一个页面),我应该先学习spring core / framework之前的其他东西,那么可能是spring MVC或spring web services在学习启动之前?
您应该了解spring的工作原理以及实例化的工作原理。基本上它会在您的项目中进行搜索并实例化每个使用 //top of your class
let locManger = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
//request user location
locManager.startUpdatingLocation()
//this is the code that sets the region based on the location
let span = MKCoordinateSpanMake(0.5, 0.5)
let location = CLLocationCoordinate2DMake((locManager.location?.coordinate.latitude)!, (locManager.location?.coordinate.longitude)!)
let region = MKCoordinateRegionMake(location, span)
yourMap.setRegion(region, animated: false)
//stop location updating
locManager.stopUpdatingLocation()
}
注释的类(@Component
,@Service
,@RestController
......等等。当您@Controller
时,会将引用传递给您的变量。
在众多网站以完全不同的方式处理事情(完全不同的注释,一些配置文件的使用)之后,它工作了,然后我使用拦截器/消息转换器,原始标头然后通过休息模板修改它助洗剂。
您可以在互联网上找到超过1 - 2年的大多数示例可能已过时(但并非总是如此)。当您搜索某些内容时请记住这一点。这是为什么有这么多实现的主要原因。
我可以找到许多资源来教我不同的软件包,但没有一个可以告诉我它们为什么工作或者从哪里开始,特别是没有什么能告诉我这些软件包是如何相互链接的。这是非常压倒性的。
这是压倒性的。它是一个具有广泛适用性的大框架。了解事情如何运作的最佳地点是:https://spring.io/docs/reference