取法其上,得乎其中

关于Java Spring框架的杂七杂八记录文

概述

最近很长一段时间都纠结于,该学习什么,最终选择了往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()方法后,两个函数都被注入进去了。

关于Java Spring框架的杂七杂八记录文

https://ku-m.cn/index.php/archives/341/

作者

KuM

发布时间

2020-04-15

许可协议

CC BY 4.0

添加新评论