浏览代码

增加了spring的笔记
增加了大数据平台的部署文档

seamew 3 年之前
父节点
当前提交
961834da9c

二进制
后端/spring/assets/image-20220319142033626.png


二进制
后端/spring/assets/image-20220319144549608.png


二进制
后端/spring/assets/image-20220319144559312.png


二进制
后端/spring/assets/image-20220320142136644.png


二进制
后端/spring/assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center.png


+ 921 - 0
后端/spring/spring.md

@@ -0,0 +1,921 @@
+> [TOC]
+
+# 1、Spring
+
+***
+
+## 1.1、简介
+
+- Spring:春天------>给软件行业带来了春天!
+
+- 2002,首次推出了Spring框架的雏形:interface21框架!
+
+- Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日发布了1.0正式版。
+
+- **Rod Johnson**,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
+
+- Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
+
+- SSH:Struct2 + Spring + Hibernate!
+
+- SSM:SpringMVC + Spring + Mybatis!
+
+官网:https://spring.io/projects/spring-framework#overview
+
+官方下载地址:https://repo.spring.io/release/org/springframework/spring/
+
+GitHub:https://github.com/spring-projects/spring-framework
+
+```xml
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>5.3.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jdbc</artifactId>
+            <version>5.3.8</version>
+        </dependency>
+```
+
+## 1.2 优点
+
+- Spring是一个开源的免费的框架(容器)!
+- Spring是一个轻量级的、非入侵式的框架!
+- 控制反转(IOC),面向切面编程(AOP)!
+- 支持事务的处理,对框架整合的支持!
+
+**总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!**
+
+## 1.3、组成
+
+![image-20220319142033626](assets/image-20220319142033626.png)
+
+## 1.4 拓展
+
+现代化的Java开发!说白了就是基于Spring的开发!
+
+- Spring Boot
+  - 一个快速开发的脚手架
+  - 基于SpringBoot可以快速的开发单个微服务
+  - 约定大于配置
+- Spring Cloud
+  - SpringCloud是基于SpringBoot实现的
+
+因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring以及SpringMVC!**承上启下的作用!**
+
+**弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱”**
+
+# 2、IOC理论推导
+
+***
+
+1. UserDao 接口
+
+   ```java
+   public interface UserDao {
+       void getUser();
+   }
+   ```
+
+2. UserDaoImpl 实现类
+
+   ```java
+   public class UserDaoImpl implements UserDao {
+       public void getUser() {
+           System.out.println("默认获取用户数据");
+       }
+   }
+   ```
+
+3. UserService 业务接口
+
+   ```java
+   public interface UserService {
+       void getUser();
+   }
+   ```
+
+4. UserServiceImpl 业务实现类
+
+   ```java
+   public class UserServiceImpl implements UserService {
+   
+       private UserDao userDao = new UserDaoImpl();
+   
+       public void getUser() {
+           userDao.getUser();
+       }
+   }
+   ```
+
+5. 测试
+
+   ```java
+   public class MyTest {
+       public static void main(String[] args) {
+   
+           //用户实际调用的是业务层,dao层他们不需要接触!
+           UserService userService = new UserServiceImpl();
+           userService.getUser();
+       }
+   }
+   ```
+
+在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!
+
+![image-20220319144549608](assets/image-20220319144549608.png)
+
+我们使用一个Set接口实现,已经发生了革命性的变化!
+
+![image-20220319144559312](assets/image-20220319144559312.png)
+
+```java
+    private UserDao userDao;
+
+    // 利用set进行动态实现值的注入!
+    public void setUserDao(UserDao userDao) {
+        this.userDao = userDao;
+    }
+```
+
+- 之前,程序是主动创建对象!控制权在程序员手上!
+- 使用了set注入后,程序不再具有主动性,而是变成了被动的接收对象!
+
+这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!这是IOC的原型!
+
+**IOC本质**
+
+**控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,**也有人认为DI只是IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
+
+采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
+**控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。**
+
+# 3、HelloSpring
+
+***
+
+1. 新建一个maven项目,编写实体类
+
+```java
+public class Hello {
+    private String str;
+
+    public String getStr() {
+        return str;
+    }
+
+    public void setStr(String str) {
+        this.str = str;
+    }
+
+    @Override
+    public String toString() {
+        return "Hello{" +
+                "str='" + str + '\'' +
+                '}';
+    }
+}
+```
+
+2. 编写xml配置文件
+
+```xml
+<?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
+        https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+
+    <!--使用Spring来创建对象,在Spring这些都称为Bean
+    类型 变量名 = new 类型();
+    Hello hello = new Hello();
+
+    id = 变量名
+    class = new的对象
+    property 相当于给对象中的属性设置一个值!
+    ref:引用Spring创建好的对象
+    value: 具体的值,基本数据类型
+        -->
+    <bean id="hello" class="com.kuang.pojo.Hello">
+        <property name="str" value="Spring"/>
+    </bean>
+</beans>
+```
+
+3. 测试
+
+```java
+public class MyTest {
+    public static void main(String[] args) {
+        //获取Spring的上下文对象!
+        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
+
+        //我们的对象现在都在Spring中的管理了,我们需要使用,直接去里面取出来就可以!
+        Hello hello = (Hello) context.getBean("hello");
+        System.out.println(hello.toString());
+    }
+}
+```
+
+**思考问题?**
+
+- Hello对象是谁创建的?
+  Hello对象是由Spring创建的。
+- Hello对象的属性是怎么设置的?
+  Hello对象的属性是由Spring容器设置的。
+
+这个过程就叫控制反转:
+
+**控制**:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
+
+**反转**:程序本身不创建对象,而变成被动的接收对象。
+
+**依赖注入**:就是利用set方法来进行注入的。
+
+IOC是一种编程思想,由主动的编程变成被动的接收。
+
+可以通过new ClassPathXmlApplicationContext去浏览一下底层源码。
+
+**OK,到了现在,我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!**
+
+# 4、IOC创建对象的方式
+
+***
+
+1. 使用无参构造创建对象,默认!
+
+2. 假设我们要使用有参构造创建对象。
+
+   1. 下标赋值
+
+   ```xml
+   <!--第一种方式:下标赋值    -->
+   <bean id="user" class="com.kuang.pojo.User">
+       <constructor-arg index="0" value="狂神说Java"/>
+   </bean>
+   ```
+
+   2. 类型
+
+   ```xml
+   <!--第二种方式:通过类型的创建,不建议使用    -->
+   <bean id="user" class="com.kuang.pojo.User">
+       <constructor-arg type="java.lang.String" value="lifa"/>
+   </bean>
+   ```
+
+   3. 参数名
+
+   ```xml
+   <!--第三种方式:直接通过参数名来设置    -->
+   <bean id="user" class="com.kuang.pojo.User">
+       <constructor-arg name="name" value="李发"/>
+   </bean>
+   ```
+
+总结:在配置文件加载的时候,容器中管理的所有对象就已经初始化了!只有一份!!!
+
+```java
+        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
+        User user = (User) context.getBean("user");
+        user.setName("123");
+        User user2 = (User) context.getBean("user");
+        System.out.println(user == user2); // true
+        System.out.println(user2.getName()); // 123
+```
+
+# 5、Spring配置
+
+***
+
+## 5.1 别名
+
+```xml
+    <!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
+    <alias name="user" alias="userNew"/>
+```
+
+## 5.2 Bean配置
+
+```xml
+    <!--
+    id:bean的唯一标识符,也就是相当于我们学的对象名
+    class:bean对象所对应的全限定名:包名+类名
+    name:也是别名,而且name可以同时取多个别名
+    可以通过空格,逗号,分号分隔
+        -->
+    <bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3;u4">
+        <property name="name" value="黑心白莲"/>
+    </bean>
+```
+
+## 5.3 import
+
+这个import。一般用于团队开发使用,它可以将多个配置文件,导入合并为一个。
+假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
+
+- 张三
+
+- 李四
+
+- 王五
+
+- applicationContext.xml
+
+  ```xml
+  <import resource="bean.xml"/>
+  <import resource="bean2.xml"/>
+  <import resource="bean3.xml"/>
+  ```
+
+使用的时候,直接使用总的配置就可以了。
+
+# 6、依赖注入
+
+***
+
+## 6.1 、构造器注入
+
+前面已经介绍过,参考**4、IOC创建对象的方式**
+
+## 6.2 、Set方式注入【重点】
+
+- 依赖注入:Set注入
+  - 依赖:bean对象的创建依赖于容器!
+  - 注入:bean对象中的所有属性,由容器来注入!
+
+【环境搭建】
+
+1. 复杂类型
+
+```java
+public class Address {
+    private String address;
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+}
+```
+
+2. 真实测试对象
+
+```java
+public class Student {
+
+    private String name;
+    private Address address;
+    private String[] books;
+    private List<String> hobbies;
+    private Map<String,String> card;
+    private Set<String> games;
+    private String wife;
+    private Properties info;
+}
+```
+
+3. beans.xml
+
+```xml
+<?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
+        https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <bean id="student" class="com.kuang.pojo.Student">
+        <!--第一种:普通值注入,value        -->
+        <property name="name" value="黑心白莲"/>
+    </bean>
+</beans>
+```
+
+4. 测试类
+
+```java
+public class MyTest {
+    public static void main(String[] args) {
+        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
+
+        Student student = (Student) context.getBean("student");
+        System.out.println(student.getName());
+    }
+}
+```
+
+5. 完善注入信息
+
+```xml
+    <bean id="address" class="com.kuang.pojo.Address">
+        <property name="address" value="西安"/>
+    </bean>
+
+    <bean id="student" class="com.kuang.pojo.Student">
+        <!--第一种:普通值注入,value        -->
+        <property name="name" value="黑心白莲"/>
+
+        <!--第二种:        -->
+        <property name="address" ref="address"/>
+
+        <!--数组        -->
+        <property name="books">
+            <array>
+                <value>红楼梦</value>
+                <value>西游记</value>
+                <value>水浒传</value>
+                <value>三国演义</value>
+            </array>
+        </property>
+
+        <!--List        -->
+        <property name="hobbies">
+            <list>
+                <value>打篮球</value>
+                <value>看电影</value>
+                <value>敲代码</value>
+            </list>
+        </property>
+
+        <!--Map        -->
+        <property name="card">
+            <map>
+                <entry key="身份证" value="123456789987456321"/>
+                <entry key="银行卡" value="359419496419481649"/>
+            </map>
+        </property>
+
+        <!--Set        -->
+        <property name="games">
+            <set>
+                <value>LOL</value>
+                <value>COC</value>
+                <value>BOB</value>
+            </set>
+        </property>
+
+        <!--NULL        -->
+        <property name="wife">
+            <null/>
+        </property>
+
+        <!--Properties        -->
+        <property name="info">
+            <props>
+                <prop key="driver">20191029</prop>
+                <prop key="url">102.0913.524.4585</prop>
+                <prop key="user">黑心白莲</prop>
+                <prop key="password">123456</prop>
+            </props>
+        </property>
+
+    </bean>
+```
+
+## 6.3 、拓展方式注入
+
+我们可以使用p命名空间和c命名空间进行注入
+
+官方解释:
+
+![在这里插入图片描述](assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center.png)
+
+使用:
+
+```xml
+<?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:p="http://www.springframework.org/schema/p"
+       xmlns:c="http://www.springframework.org/schema/c"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        https://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <!--p命名空间注入,可以直接注入属性的值:property-->
+    <bean id="user" class="com.kuang.pojo.User" p:name="黑心白莲" p:age="20"/>
+
+    <!--c命名空间注入,通过构造器注入:constructor-args-->
+    <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22"/>
+
+</beans>
+```
+
+测试:
+
+```java
+    @Test
+    public void test2(){
+        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
+
+        User user = context.getBean("user",User.class);
+        System.out.println(user);
+
+        User user2 = context.getBean("user2",User.class);
+        System.out.println(user2);
+    }
+```
+
+注意点:p命名空间和c命名空间不能直接使用,需要导入xml约束
+
+```xml
+       xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:c="http://www.springframework.org/schema/c"
+```
+
+## 6.4 、bean的作用域
+
+![在这里插入图片描述](assets/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpNjQzOTM3NTc5,size_16,color_FFFFFF,t_70#pic_center.png)
+
+1. 单例模式(Spring默认机制)
+
+```xml
+<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="singleton"/>
+```
+
+2. 原型模式:每次从容器中get的时候,都会产生一个新对象!
+
+```xml
+<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="prototype"/>
+```
+
+3. 其余的request、session、application、这些只能在web开发中用到!
+
+# 7、bean的自动装配
+
+***
+
+- 自动装配是Spring满足bean依赖的一种方式
+- Spring会在上下文中自动寻找,并自动给bean装配属性
+
+在Spring中有三种装配的方式:
+
+1. 在xml中显式的配置;
+2. 在java中显式配置;
+3. 隐式的自动装配bean【重要】
+
+## 7.1 、测试
+
+环境搭建:创建项目,一个人有两个宠物!
+
+```xml
+    <bean id="cat" class="com.kuang.pojo.Cat"/>
+    <bean id="dog" class="com.kuang.pojo.Dog"/>
+
+    <bean id="people" class="com.kuang.pojo.People">
+        <property name="name" value="小白莲"/>
+        <property name="cat" ref="cat"/>
+        <property name="dog" ref="dog"/>
+    </bean>
+```
+
+## 7.2、 ByName自动装配
+
+```xml
+        <!--
+        byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
+        这里的id值得是set后面的值,会自动转换为小写
+            -->
+        <bean id="people" class="com.kuang.pojo.People" autowire="byName">
+            <property name="name" value="小白莲"/>
+        </bean>
+```
+
+## 7.3 、ByType自动装配
+
+```xml
+        <!--
+        byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
+ 必须唯一,不能有两个
+            -->
+        <bean id="people" class="com.kuang.pojo.People" autowire="byType">
+            <property name="name" value="小白莲"/>
+        </bean>
+```
+
+小结:
+
+- ByName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
+- ByType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
+
+## 7.4 、使用注解实现自动装配
+
+jdk1.5支持的注解,Spring2.5就支持注解了!
+
+要使用注解须知:
+
+1. 导入约束
+
+2. 配置注解的支持
+
+   ```xml
+   <?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
+   	        https://www.springframework.org/schema/beans/spring-beans.xsd
+   	        http://www.springframework.org/schema/context
+   	        https://www.springframework.org/schema/context/spring-context.xsd">
+   		
+   		<!--开启注解的支持    -->
+           <context:annotation-config/>
+   </beans>
+   ```
+
+**@Autowired**
+
+直接在属性上使用即可!也可以在set方法上使用!
+
+使用Autowried我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字ByName!
+
+**科普:**
+
+> @Nullable 字段标记了了这个注解,说明这个字段可以为null;
+
+```java
+public @interface Autowired {
+    boolean required() default true;
+}
+```
+
+测试代码
+
+```java
+public class People {
+    //如果显式定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
+    @Autowired(required = false)
+    private Cat cat;
+    @Autowired
+    private Dog dog;
+    private String name;
+}
+```
+
+如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
+
+```java
+public class People {
+    @Autowired
+    @Qualifier(value = "cat111")
+    private Cat cat;
+    @Autowired
+    @Qualifier(value = "dog222")
+    private Dog dog;
+    private String name;
+}
+```
+
+**@Resource**
+
+```java
+public class People {
+
+    @Resource
+    private Cat cat;
+
+    @Resource
+    private Dog dog;
+}
+```
+
+小结:
+
+@Resource和@Autowired的区别:
+
+- 都是用来自动装配的,都可以放在属性字段上
+- @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
+- @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
+- 执行顺序不同:@Autowired通过byType的方式实现。@Resource默认通过byName的方式实现
+
+# 8、使用注解开发
+
+***
+
+在Spring4之后,要使用注解开发,必须要保证aop的包导入了
+
+![image-20220320142136644](assets/image-20220320142136644.png)
+
+使用注解需要导入约束,配置注解的支持!
+
+```xml
+	<?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
+		        https://www.springframework.org/schema/beans/spring-beans.xsd
+		        http://www.springframework.org/schema/context
+		        https://www.springframework.org/schema/context/spring-context.xsd">
+			
+			<!--开启注解的支持    -->
+	        <context:annotation-config/>
+	</beans>
+```
+
+> **Bean的实现**
+
+我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!
+
+1. 配置扫描那些包下的注解
+
+```xml
+<!--指定注解扫描包-->
+<context:component-scan base-package="com.kuang.pojo"/>
+```
+
+2. 在指定包下编写类,增加注释
+
+```java
+@Component("user")
+// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
+public class User {
+   public String name = "秦疆";
+}
+```
+
+3. 测试
+
+```java
+@Test
+public void test(){
+   ApplicationContext applicationContext =
+       new ClassPathXmlApplicationContext("beans.xml");
+   User user = (User) applicationContext.getBean("user");
+   System.out.println(user.name);
+}
+```
+
+> **属性注入**
+
+使用注解注入属性
+
+1. 可以不用提供set方法,直接在直接名上添加@value("值")
+
+   ```java
+   @Component("user")
+   // 相当于配置文件中 <bean id="user" class="当前注解的类"/>
+   public class User {
+      @Value("秦疆")
+      // 相当于配置文件中 <property name="name" value="秦疆"/>
+      public String name;
+   }
+   ```
+
+2. 如果提供了set方法,在set方法上添加@value("值")
+
+   ```java
+   @Component("user")
+   public class User {
+   
+      public String name;
+   
+      @Value("秦疆")
+      public void setName(String name) {
+          this.name = name;
+     }
+   }
+   ```
+
+> **衍生注解**
+
+我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
+
+**@Component三个衍生注解**
+
+为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。
+
+- @Controller: web层
+- @Service:service层
+- @Repository:dao层
+
+写上这些注释,就相当于将这个类交给Spring管理装配了!
+
+> **自动装配注解**
+
+在Bean的自动装配已经讲过了,可以回顾!
+
+- @Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value = "xxx")去配置。
+- @Nullable 字段标记了了这个注解,说明这个字段可以为null;
+- @Resource:自动装配通过名字,类型。
+
+> **作用域**
+
+@scope
+
+- singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
+- prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
+
+```java
+@Component
+@Scope("singleton")
+public class User {
+
+    //相当于  <property name="name" value="白莲"/>
+    @Value("白莲")
+    public String name;
+}
+```
+
+> **小结**
+
+**xml与注解:**
+
+- xml更加万能,适用于任何场合!维护简单方便
+- 注解不是自己类使用不了,维护相队复杂!
+
+**xml与注解最佳实践:**
+
+- xml用来管理bean;
+- 注解只负责完成属性的注入;
+- 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
+
+```xml
+    <!--指定要扫描的包,这个包下的注解就会生效-->
+    <context:component-scan base-package="com.kuang"/>
+    <!--开启注解的支持    -->
+    <context:annotation-config/>
+```
+
+作用:
+
+- 进行注解驱动注册,从而使注解生效
+- 用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
+- 如果不扫描包,就需要手动配置bean
+- 如果不加注解驱动,则注入的值为null!
+
+# 9、使用Java的方式配置Spring
+
+***
+
+JavaConfig 原来是 Spring 的一个子项目,它通过 Java 类的方式提供 Bean 的定义信息,在 Spring4 的版本, JavaConfig 已正式成为 Spring4 的核心功能 。
+
+实体类
+
+```java
+//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
+@Component
+public class User {
+    private String name;
+
+    public String getName() {
+        return name;
+    }
+
+    @Value("黑心白莲") //属性注入值
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "User{" +
+                "name='" + name + '\'' +
+                '}';
+    }
+}
+```
+
+配置文件
+
+```java
+// 这个也会Spring容器托管,注册到容器中,因为它本来就是一个@Component
+// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
+@Configuration
+@ComponentScan("com.kuang.pojo")
+// 引入多个配置类,合并
+@Import(KuangConfig2.class)
+public class KuangConfig {
+
+    // 注册一个bean,就相当于我们之前写的一个bean标签
+    // 这个方法的名字,就相当于bean标签中id属性
+    // 这个方法的返回值,就相当于bean标签中的class属性
+    @Bean
+    public User user(){
+        return new User(); // 就是返回要注入到bean的对象!
+    }
+}
+```
+
+测试类
+
+```java
+public class MyTest {
+    public static void main(String[] args) {
+
+        //如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的class对象加载!
+        ApplicationContext context = new AnnotationConfigApplicationContext(KuangConfig.class);
+
+        User user = context.getBean("user", User.class);
+        System.out.println(user.getName());
+    }
+}
+```
+
+这种纯Java的配置方式,在SpringBoot中随处可见!
+

+ 93 - 31
部署文档/云平台/安装云平台环境.md

@@ -25,7 +25,7 @@
 
 ## 1.2、安装前的准备工作
 
-```shell
+```sh
 # 关闭防火墙
 systemctl stop firewalld && systemctl disable firewalld
 
@@ -72,7 +72,7 @@ clock -w
 ```
 
 上述操作执行完毕后重启
-```shell
+```sh
 reboot
 ```
 三台服务器,开始下一步的安装
@@ -82,7 +82,7 @@ reboot
 
 ## 2.1、离线安装Docker
 
-```shell
+```sh
 # 1.创建目录存放相应的安装包
 mkdir -p /opt/package/docker
 
@@ -106,7 +106,7 @@ docker --version
 ## 2.2、离线安装Docker-compose
 
 将安装包目录下的docker-compose-linux-x86_64文件上传到服务机的```/opt/package```目录下使用命令
-```shell
+```sh
 // 1.将下载好的文件传入linux系统中,并重命名未docker-compose
 mv docker-compose-linux-x86_64 docker-compose
 // 2.给予docker-compose文件可执行权限
@@ -128,18 +128,18 @@ docker-compose --version
 ## 3.1、安装Harbor
 
 1. 将压缩包harbor-offline-installer-v2.1.5.tgz上传到
-```shell
+```sh
 /opt/package/
 ```
 目录下
 2. 解压该压缩包
-```shell
+```sh
 tar xf harbor-offline-installer-v2.1.5.tgz
 ```
 3. 修改harbor安装的配置文件
 
 首先备份一份压缩包
-```shell
+```sh
 # 复制配置文件内容到harbor.yml 中(安装时只识别harbor.yml)
 cp harbor.yml.tmpl  harbor.yml         
 # 用于存放harbor的持久化数据
@@ -195,7 +195,7 @@ echo "10.168.59.60  server.harbor.com">> /etc/hosts
 ```
 
 docker添加harbor配置-----注意这里要加harbor的端口号,这里配置的端口号为上述harbor配置文件的端口号
-```shell
+```sh
 mkdir -p /etc/docker
 
 tee /etc/docker/daemon.json <<-'EOF'
@@ -219,7 +219,7 @@ systemctl daemon-reload && systemctl restart docker
 ```
 
 输入命令
-```shell
+```sh
 # 重新启动harbor,因为docker重启但是harbor不能自动重启
 cd /opt/package/
 docker-compose start
@@ -247,7 +247,7 @@ scp -r kube1.9.0.tar.gz root@192.168.238.22:/opt/package/k8s
 
 ## 4.2 、解压安装主从
 
-```shell
+```sh
 # 1.master下,进入/opt/package/k8s目录下解压,执行脚本
 tar -zxvf kube1.19.0.tar.gz
 cd kube/shell 
@@ -277,13 +277,13 @@ scp -r /etc/kubernetes/admin.conf node2:/etc/kubernetes/
 
  1. 在master节点生成token
 
-    ```shell
+    ```sh
     kubeadm token create --print-join-command
     ```
 
     效果如下
 
-    ```shell
+    ```sh
     [root@master shell]# kubeadm token create --print-join-command
     W1009 17:15:31.782757   37720 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
     kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
@@ -291,13 +291,13 @@ scp -r /etc/kubernetes/admin.conf node2:/etc/kubernetes/
 
    2. 在node1和node2中执行下面的命令------注意这里要上面生产的命令
 
-      ```shell
+      ```sh
       kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
       ```
 
       结果如下
 
-      ```shell
+      ```sh
       [root@node1 shell]# kubeadm join 192.168.0.90:6443 --token ul68zs.dkkvpwfex9rpzo0d     --discovery-token-ca-cert-hash sha256:3e3ee481f5603621f216e707321aa26a68834939e440be91322c62eb8540ffce
       [preflight] Running pre-flight checks
       	[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
@@ -318,7 +318,7 @@ scp -r /etc/kubernetes/admin.conf node2:/etc/kubernetes/
       
 3. 给node1和node2添加执行权限
 
-```shell
+```sh
 # 在node1和node2执行一下命令
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
@@ -335,7 +335,7 @@ kubectl get nodes
 watch kubectl get pod -n kube-system -o wide 
 效果如下	
 
-```shell
+```sh
    [root@master shell]# watch kubectl get pod -n kube-system -o wide
    Every 2.0s: kubectl get pod -n kube-system -o wide                                                                                                                  Fri Oct  9 17:45:03 2020
      NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
@@ -355,7 +355,7 @@ watch kubectl get pod -n kube-system -o wide
 ```
 kubectl get nodes
 效果如下
-```shell
+```sh
    [root@master shell]# kubectl get nodes
      NAME     STATUS   ROLES    AGE     VERSION
      master   Ready    master   22m     v1.19.0
@@ -374,7 +374,7 @@ kubectl get nodes
 
 1. 将本地nfs离线包上传至服务器及各个节点的/opt/package/nfs文件夹下
 
-   ```shell
+   ```sh
    scp -r nfs master:/opt/package
    scp -r nfs node1:/opt/package
    scp -r nfs n:/opt/package
@@ -382,7 +382,7 @@ kubectl get nodes
    
 2. 安装服务端(master节点操作)
 
-   ```shell
+   ```sh
    # 进入master节点内/opt/package/nfs文件夹内执行以下命令
    # 进入/opt/package/nfs
    cd /opt/package/nfs
@@ -404,7 +404,7 @@ kubectl get nodes
    /nfs/data     	<world>
    ```
 3. 安装NFS客户端(三台服务机操作)
-```shell
+```sh
 # 进入node1,node2节点内/opt/package/nfs文件夹内执行以下命令
 cd /opt/package/nfs
 rpm -ivh *.rpm  --force --nodeps # 注意如果不能安装选择  nfs.zip文件
@@ -412,7 +412,7 @@ systemctl start nfs && systemctl enable nfs
 ```
 
 4. K8S中安装NFS(任意K8S节点,这里选择master节点)
-```shell
+```sh
 # 1.进入/opt/package/nfs目录
 cd /opt/package/nfs
 # 2.载入docker镜像
@@ -488,7 +488,7 @@ managed-nfs-storage (default)   fuseim.pri/ifs   Delete          Immediate
 ## 5.1、将离线包上传至harbor仓库(该操作只需在master节点进行)
 
 将安装包目录下的kubesphere文件夹上传至服务机master节点的
-```shell
+```sh
 /opt/package/
 ```
 目录下
@@ -498,7 +498,7 @@ managed-nfs-storage (default)   fuseim.pri/ifs   Delete          Immediate
 新建一个kubesphere项目
 ![image-20211111101212415](assets/image-20211111101212415.png)
 
-```shell
+```sh
 # 在服务机master节点中执行命令
 # 重新启动harbor,因为docker重启但是harbor不能自动重启
 cd /opt/package/harbor
@@ -515,7 +515,7 @@ chmod +x offline-installation-tool.sh
 
 ## 5.2、最小化安装kubesphere
 
-```shell
+```sh
 # 执行以下命令
 # 1.编辑cluster-configuration.yaml添加您的私有镜像仓库
 vim cluster-configuration.yaml
@@ -536,14 +536,14 @@ kubectl get pods -A
 ![image-20211110231108730](assets/image-20211110231108730-16365570741011.png)
 ![image-20211110231233626](assets/image-20211110231233626.png)
 
-```shell
+```sh
 # 4.等待ks-installer容器运行完毕,执行
 kubectl apply -f cluster-configuration.yaml
 ```
 
 ## 5.3、检查安装日志
 
-```shell
+```sh
 # 检查安装日志等待安装成功
 kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f
 ```
@@ -558,7 +558,7 @@ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=
 2. KubeSphere DevOps
 3. KubeSphere kubeedge
 
-```shell
+```sh
 # 1.编辑cluster-configuration.yaml
 vim cluster-configuration.yaml
 
@@ -583,7 +583,7 @@ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=
 
 ## 5.5、开放30881端口(重要--master节点操作)
 
-```shell
+```sh
 kubectl -n kubesphere-system patch svc ks-apiserver -p '{"spec":{"type":"NodePort","ports":[{"port":80,"protocal":"TCP","targetPort":9090,"nodePort":30881}]}}'
 ```
 
@@ -620,14 +620,14 @@ kubectl -n kubesphere-system patch svc ks-apiserver -p '{"spec":{"type":"NodePor
 ## 6.1、harbor仓库登录显示400错误
 
 ![image-20211123200112617](assets/image-20211123200112617.png)
-```shell
+```sh
 Error response from daemon: login attempt to https://server.harbor.com/v2/ failed with status: 400 Bad Request
 ```
 
 查询相关文档发现是nginx的配置出现了问题
 [Docker 登录返回 400 错误请求](https://github.com/goharbor/harbor/issues/7159)
 
-```shell
+```sh
 #修改方式如下
 #1.进入harbor仓库位置
 cd /opt/package/software/harbor
@@ -653,11 +653,73 @@ docker restart e39629e9c2c4
 
 ![image-20220317164430599](assets/image-20220317164430599.png)
 
-```shell
+```sh
 # 当创建单机版的 k8s 时,这个时候 master 节点是默认不允许调度 pod 的,需要执行
 kubectl taint nodes --all node-role.kubernetes.io/master-
 ```
 
+## 6.3、kubesphere的api-server无法启动
+
+api-server显示报错---无法申请资源,原因是docker的进程数不够,增加一下的配置重启docker就行
+
+```shell
+echo "
+[Unit]
+Description=Docker Application Container Engine
+Documentation=https://docs.docker.com
+# BindsTo=containerd.service
+# After=network-online.target firewalld.service containerd.service
+After=network-online.target firewalld.service
+Wants=network-online.target
+# Requires=docker.socket
+
+[Service]
+Type=notify
+# the default is not to use systemd for cgroups because the delegate issues still
+# exists and systemd currently does not support the cgroup feature set required
+# for containers run by docker
+# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
+ExecStart=/usr/local/bin/dockerd
+ExecReload=/bin/kill -s HUP $MAINPID
+TasksMax=infinity
+TimeoutSec=0
+RestartSec=2
+Restart=always
+
+# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
+# Both the old, and new location are accepted by systemd 229 and up, so using the old location
+# to make them work for either version of systemd.
+StartLimitBurst=3
+
+# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
+# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
+# this option work for either version of systemd.
+StartLimitInterval=60s
+
+# Having non-zero Limit*s causes performance problems due to accounting overhead
+# in the kernel. We recommend using cgroups to do container-local accounting.
+LimitNOFILE=infinity
+LimitNPROC=infinity
+LimitCORE=infinity
+
+# Comment TasksMax if your systemd version does not support it.
+# Only systemd 226 and above support this option.
+# TasksMax=infinity
+
+# set delegate yes so that systemd does not reset the cgroups of docker containers
+Delegate=yes
+
+# kill only the docker process, not all processes in the cgroup
+KillMode=process
+
+[Install]
+WantedBy=multi-user.target
+" > /etc/systemd/system/docker.service
+
+# 重启docker
+systemctl daemon-reload && systemctl restart docker
+```
+
 
 
 # 附录----安装软件的版本

二进制
部署文档/大数据平台/assets/image-20220320185243246.png


文件差异内容过多而无法显示
+ 0 - 116
部署文档/大数据平台/solr and atlas.md


文件差异内容过多而无法显示
+ 620 - 0
部署文档/大数据平台/大数据平台环境搭建.md


+ 128 - 0
部署文档/大数据平台/大数据监控安装文档.md

@@ -0,0 +1,128 @@
+> [TOC]
+
+# 监控安装文档
+
+# 1. `prometheus`
+
+1. 上传`prometheus`安装包至`lab3`服务器`/opt/modules/`目录下并解压
+
+   ```shell
+   tar -zxf prometheus-2.32.1.linux-amd64.tar.gz
+   ```
+
+2. 进入`/opt/modules/opt/modules/prometheus-2.32.1`目录,修改`prometheus.yml`文件
+
+   ```shell
+   vi prometheus.yml
+   ```
+
+   将配置信息做如下修改
+
+   ```shell
+   scrape_configs:
+     # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
+     - job_name: "prometheus"
+   
+       # metrics_path defaults to '/metrics'
+       # scheme defaults to 'http'.
+   
+       static_configs:
+         - targets: ["lab3:9090"]
+     - job_name: "node exporter"
+   
+       # metrics_path defaults to '/metrics'
+       # scheme defaults to 'http'.
+   
+       static_configs:
+         - targets: ['lab1:8100', 'lab2:8100', 'lab3:8100']
+     - job_name: "kafka exporter"
+   
+       # metrics_path defaults to '/metrics'
+       # scheme defaults to 'http'.
+   
+       static_configs:
+         - targets: ['lab3:9308']
+   ```
+
+3. 在`/opt/modules/opt/modules/prometheus-2.32.1`目录下启动`prometheus`
+
+   ```shell
+   nohup ./prometheus --config.file=prometheus.yml > ./prometheus.log 2>&1 &
+   ```
+
+4. 查看`9090`端口状态或浏览器访问`http://lab3:9090`验证是否成功
+
+   ```shell
+   lsof -i:9090
+   ```
+
+# 2. `node_exporter`
+
+1. 上传`node_exporter`安装包至`lab3`服务器`/opt/modules/`目录下并解压
+
+   ```shell
+   tar -zxf node_exporter-1.3.1.linux-amd64.tar.gz
+   ```
+
+2. 进入`/opt/modules/opt/modules/node_exporter-1.3.1`目录,启动`node_exporter`
+
+   ```shell
+   nohup ./node_exporter --web.listen-address=:8100 &
+   ```
+
+3. 查看`8100`端口状态或浏览器访问`http://lab3:8100/metrics`验证是否成功
+
+   ```shell
+   lsof -i:8100
+   ```
+
+4. 在`lab1`和`lab2`上重复上述步骤
+
+# 3. `kafka_exporter`
+
+1. 上传`kafka_exporter`安装包至`lab3`服务器`/opt/modules/`目录下并解压
+
+   ```shell
+   tar -zxf kafka_exporter-1.4.2.linux-amd64.tar.gz
+   ```
+
+2. 进入`/opt/modules/opt/modules/kafka_exporter-1.4.2`目录,启动`kafka_exporter`
+
+   ```shell
+   nohup ./kafka_exporter --kafka.server=lab3:9092 > kafka_exporter.log  --web.listen-address=:9308 &
+   ```
+
+3. 查看`9308`端口状态或浏览器访问`http://lab3:9308/metrics`验证是否成功
+
+   ```shell
+   lsof -i:9308
+   ```
+
+# 4. `grafana`
+
+1. 上传`grafana`至`lab3`服务器`/opt/modules/`目录
+
+2. 进入`/opt/modules/grafana-8.3.4`目录,启动`grafana`
+
+   ```shell
+   nohup ./bin/grafana-server web > ./grafana.log 2>&1 &
+   ```
+
+3. 查看`3000`端口状态或浏览器访问`http://lab3:3000/`验证是否成功
+
+   ```shell
+   lasof -i:3000
+   ```
+
+4. 访问`http://lab3:3000`, 用户和密码均为`admin`
+5. 进入左侧设置,配置`prometheus`数据源及`mysql`数据源
+
+# 附录
+
+| 软件           | 版本   |
+| -------------- | ------ |
+| prometheus     | 2.32.1 |
+| node_exporter  | 1.3.1  |
+| kafka_exporter | 1.4.2  |
+| grafana        | 8.3.4  |
+

部分文件因为文件数量过多而无法显示