概述
最近很长一段时间都纠结于,该学习什么,最终选择了往JavaWeb方向学习。因为Java时间悠久的缘故非常杂乱,于是上网上翻了很多所谓的路线图、学习记录。最终决定先学习spring。
首先明确第一点:
前后端分离是大趋势。这样的好处是,前端工程师与后端工程师可以同时开发,只需要由后端提供前端接口,然后前端使用ajax方式进行接收。
所以,JSP啊,什么模板啊,都并不需要进行学习。去除了这一点,还剩:Servlet/Spring/Spring Boot
什么是Servlet? 这玩意是Javaweb中提供的一个接口。而其他三个框架都基于这个东西,如果闲的没事可以看一下。所谓spring简化了servlet编写的过程。但由于spring的发展,就偏离了简化的初衷,之后spring boot又在spring的基础上再简化一次23333...
所以基于这个来说,我们第一步应该去学习spring,当了解了spring的原理之后,再进行学习spring boot。
环境配置
这里需要配置Maven,这个东西类似于npm或者pip这些包管理器,不过前两者都是通过命令行进行安装库,而maven是通过xml进行配置。
我们需要配置两个东西:下载库的安装路径、从哪里下载。前者不用解释,后者是因为maven的源是国外,下载速度会非常慢,我们需要配置到阿里云的源。
配置项在maven路径下的/conf/settings.xml
配置仓库
<localRepository>/Volumes/data/java/maven/maven-pro</localRepository>
配置阿里云源
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
创建一个Spring项目
在Maven库中搜索 “spring-webmvc”,获得spring的配置。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
在项目路径下的pom.xml中添加一个<dependencies>标签,然后把上面的配置装进去。
保存一下,等待maven装配完毕。
控制反转思想(IOC)
刚学习完简单的记录自己的理解,在这里就不记录如何推到出该思想了。
简单的来说,目的是降低代码之间的耦合度。将究竟使用哪一个代码的权利反转给“用户”。一般采用依赖注入(DL)的方式进行实现该思想。
反转:程序本身不创建对象,变成被动的接收对象。
依赖注入:利用set方法进行诸如。
使用xml配置获得对象
前面简单的了解了控制反转的思想,下面要说的是:在spring中整体就采用了这个思想!
在spring中我们不需要自己去主动的new一些对象了,而采用了由spring统一管理对象,bean就是管理这些对象的容器,我们需要将自己的类在xml中进行声明,然后再通过ClassPathXmlApplicationContext() 获得我们的对象。
简单的类
package com.kum.pojo;
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在xml中注册
使用bean标签进行创建,id为名称,class为对应的类。然后使用property可以对我们的对象进行一个初始化复制。当然,获得这个对象的时候,我们使用set方法也是一样的。
<?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="com.kum.pojo.Hello">
<property name="name" value="spring"/>
</bean>
</beans>
获得对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.getName());
使用注解的方式获得对象
当xml的配置项很多的时候会出现非常杂乱的局面,在spring中还可以在类中使用注解。
不过仍然需要xml进行设置。
以下xml的含义是指:扫描 com.kum.pojo 下的注解。
<?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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.kum.pojo"/>
</beans>
设置好上面的xml我们就不再需要为每一个类设置bean标签啥的了。直接在类上输入@Component,其功能等价于bean标签,代表创建一个组件。 而@Value等价于property标签。
@Component
public class Hello {
@Value("2333")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
然后使用ClassPathXmlApplicationContext("bean.xml")获取这个xml,进行获取即可。
完全抛弃xml的方式
创建一个config类,然后使用@Configuration注解声明这是一个配置类,然后使用@ComponentScan("com.kum.pojo")设置注解扫描的范围。
之后下面使用@Bean注解,等价于bean标签。getHello这个名字对应的是bean标签中的name,后面就用它来找到这个对象。
@Configuration
@ComponentScan("com.kum.pojo")
public class config {
@Bean
public Hello getHello(){
return new Hello();
}
}
获得这个类的方法变为:AnnotationConfigApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(config.class);
Hello hello = context.getBean("getHello", Hello.class);
System.out.println(hello.getName());
自动装配
在Hello类中增加一个Dog类型的类。
这里引用了lombok,可以自动生成get/set、有参/无参 构造方法。降低我们类的代码量。
@Data // get/set
@AllArgsConstructor // 有参
@NoArgsConstructor // 无参
@Component
public class Dog {
@Value("旺财")
private String name;
@Value("15")
private int age;
}
只需要使用Autowired注解就可以自动从容器中获得这个对象,如果不使用Qualifier注解,spring会自动寻找类型相同的bean,如果使用了则以Qualifier的value(id)进行查找。
@Autowired
@Qualifier(value = "dog")
private Dog dog;
Aop 面向切面编程
其实说白了就是制定一个目标,以这个目标为切入点进行注入代码。在不改动之前代码的前提下进行增加功能。比如添加日志..
1.开启注解扫描
<aop:aspectj-autoproxy/> //xml版
@EnableAspectJAutoProxy // 注解版
2.实现切面类
使用Aspect注解声明这是一个切面类。然后使用After(方法运行后)注解或Before(方法运行前)注解设置什么时候运行下面的方法(并不止这两个),而其参数execution则是声明执行的目标。这里叫做execution表达式。
其含义为: 分为4部分。 类型 -> 包名 -> 方法名 -> 方法参数
如果不限制,则输入*。 如果想注入到Hello类下的所有方法,则是:
"execution(* com.kum.pojo.Hello.*(..))"
注意,第4部分如果不限制参数就填“..”,下面的show()之所以不填是因为他本身就没有参数。不过为了规范,最好填写。
@Aspect //声明这是一个切面类
@Component
public class aop {
@After("execution(* com.kum.pojo.Hello.show())")
public void After(){
System.out.println("方法执行后");
}
@Before("execution(* com.kum.pojo.Hello.show())")
public void Before(){
System.out.println("方法执行前");
}
}
如下图,可以发现,在执行show()方法后,两个函数都被注入进去了。