spring教程

## Spring教程

### 1、Spring简介

官网API: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-p-namespace

Spring Framework 为现代基于 Java 的企业应用程序提供了一个全面的编程和配置模型 - 在任何类型的部署平台上。

Spring 的一个关键元素是应用程序级别的基础设施支持:Spring 专注于企业应用程序的“管道”,以便团队可以专注于应用程序级业务逻辑,而无需与特定部署环境产生不必要的联系。

Spring是Full-stack轻量级框架, Java EE的春天,当前主流框架。数据访问层Dao  MVC部分,Web部分。

Spring的核心理念就是面向bean的编程。

### 2、控制反转

将组件对象的控制权由代码本身转移到外部容器。

发现传统方式,如果切换了实现类就必须在代码中更改实现类,这种方式就是耦合度很高,违反了spring的思想,组件化配置。

### 3、Spring程序开发步骤
##### 3.1.添加依赖spring-webmvc 

导入基本包坐标:

~~~xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.6</version>
</dependency>
~~~

##### 3.2.编写Dao接口和实现类

##### 3.3创建Spring核心配置文件

~~~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
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
   
</beans>
~~~

##### 3.4.在Spring配置文件中配置UserDaoImpl

~~~xml
<bean id="usreMapper" class="cn.hxzy.dao.impl.UserMapperImpl"></bean>
~~~

##### 3.5.使用Spring的API获得Bean实例

~~~java
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
public boolean save() {
    UserMapper userMapper = (UserMapper) context.getBean("userMapper");
    Integer count = userMapper.save();
    if (count > 0) {
        return true;
    }
    return false;
}
~~~

### 4、依赖注入

把对象的属性值,通过容器来注入到对象实体中去

#### 4.1、构造方法注入

##### 4.1.1 按照构造函数的参数索引值位置进行注入

```xml
<bean id="user" class="cn.hxzy.pojo.User">
    <constructor-arg index="0" value="zhangsan"/>
    <constructor-arg index="1" value="20"/>
</bean>
```

 ##### 4.1.2 按照构造函数的参数类型进行注入

注意,如果按类型进行匹配注入,配置的是基本数据类型,则在class中定义的属性也必须为基本数据类型。如果为包装类,定义的时候也必须为包装类型。

~~~xml
<bean id="user" class="cn.hxzy.pojo.User">
    <constructor-arg type="java.lang.String" value="lisi"/>
    <constructor-arg type="java.lang.Integer" value="24"/>
</bean>
~~~

bean标签的作用范围

| **singleton** | **默认的,单例的**                                           |
| ------------- | ------------------------------------------------------------ |
| **prototype** | **多例的**                                                   |
| **request**   | **SpringWeb**应用中,创建一个bean对象后,存入到request作用域 |
| **session**   | **SpringWeb**应用中,创建一个bean对象后,存入到sessiont作用域 |



##### 4.1.3 引用注入

~~~xml
<bean id="user" class="cn.hxzy.pojo.User">
    <constructor-arg index="0" value="zhangsan"/>
    <constructor-arg index="1" value="20"/>
    <constructor-arg ref="dog"/>
</bean>
<bean id="dog" class="cn.hxzy.pojo.Dog">
    <constructor-arg index="0" value="旺财"/>
    <constructor-arg index="1" value="3"/>
</bean>
~~~

#### 4.2、设值注入

##### 4.2.1 properties属性注入

setter器

~~~java
public void setUserName(String userName) {
     this.userName = userName;
}
~~~

xml配置

~~~xml
<!-- 设值注入-->
<bean id="stu" class="cn.hxzy.pojo.Student">
    <property name="userName" value="qyy"/>
</bean>
~~~

##### 4.2.2 p-namespace p命名空间注入

配置,头文件中引入

~~~xml
xmlns:p="http://www.springframework.org/schema/p"
~~~

#### 4.3 注入其他复杂数据类型

复杂数据类型的bean配置

~~~xml
<bean id="data" class="cn.hxzy.news.test.DataCategroy">
    <property name="strs">
        <array>
            <value>html</value>
            <value>vue</value>
            <value>spring</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>java</value>
            <value>jdbc</value>
            <value>maven</value>
        </list>
    </property>
    <property name="map">
        <map>
            <entry key="ch" value="中国"/>
            <entry key="en" value="英国" />
            <entry key="us" value="美国"/>
            <entry key="ru" value="俄罗斯"/>
        </map>
    </property>
</bean>
~~~

### 5、Bean标签的范围配置

Java中共有23种设计模式。单例模式是其中之一,在应用程序运行起来,类加载后,内存中产生了一个唯一的对象。

单例模式分为两种:1、懒汉模式   2、饿汉模式



### 6、Bean的自动装配方式

#####  6.1 XML配置

~~~xml
<bean id="user" class="cn.hxzy.pojo.User" autowire="byName">
    <property name="userName" value="zhangsan"/>
    <property name="userAge" value="30"/>
    <property name="userId" value="100"/>
</bean>
<bean id="dog" class="cn.hxzy.pojo.Dog">
    <property name="dogColor" value="黄色"/>
    <property name="dogName" value="旺财"/>
</bean>
~~~

byName
会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid

byType
会自动在容器上下文中查找,和自己对象属性类型相同的bean,如果在容器存在相同类型的对象,则不能使用byType。



##### 6.2 java中显式的进行配置

使用java的注解,也必须spring配置文件中配置context约束

```
@Resource与@Autowired的区别:
@Resource是java的注解,默认是按照名称进行装配,相当于是@Autowired加@Qualifier(value = "user")的合体
@Autowired是spring的注解,默认是按照类型进行装配

相同点
   都是用来自动装配的,都可以放在属性字段上
不同点
    @Autowired通过byType的方式实现,必须要求这个对象存在
    @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现。
```

##### 6.2 注解配置

参考7.5



### 7、使用注解实现自动装配

步骤:

##### 7.1 引入依赖

##### 7.2 编写spring的核心配置文件

##### 7.3 引入context约束配置信息

~~~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">


</beans>
~~~

##### 7.4 配置注解的支持

~~~xml
<!--启用注解配置-->
<context:annotation-config/>
~~~

##### 7.5 常用注解的说明

@Component //相当于在spring配置文件中定义的bean节点,当容器加载的时候,扫描包以后就会进行注册到IOC容器

根据@Component注解衍生出一些注解:

@Repository  代表数据访问层

@Service  代表业务逻辑层, 通常情况会给他加名称 @Service(value = "userService")

@Controller 代表控制层

<hr/>

@PropertySource("classpath:application.properties")读取静态资源目录下指定名称的properties文件

@Value("${name}")

~~~java
package cn.hxzy.news.config;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration  //配置类
@PropertySource(value="classpath:person.properties",encoding ="utf-8" )
public class PersonConfig {

    @Value("${personname}") //属性文件数据注入
    private String personname;

    @Value("${personage}")
    private int personage;

    @Bean
    public Person getPerson() {
        Person p1=new Person();
        p1.setAge(personage);
        p1.setName(personname);
        return p1;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
        private String name;
        private int age;
    }
}

~~~



@Configration 相当于spring核心配置文件里面的beans

@Autowired 注解实现的bean的自动装配,默认是按照类型去装配的,如果容器中出现了两个类型相同的bean,则需要添加注解

@Qualifier(value = "user")来进行区分

@Configration和@Bean 与 @Component的区别:

@Configration和@Bean一般用于第三方组件要注册到spring 容器中实用,比如说要把mybatis中的PageHelper等类注册到容器中。

@Component一般用于自定义的类

@Mapper 这个注解不属于spring框架,属于mybatis,一般会在映射的接口文件上标注此注解

```properties
@Autowired //根据类型自动装配,如果系统中出现了两个相同类型的对象,则需要使用@Qualifier
@Qualifier(value = "jdbcMysqlDao")//根据名称来自动装配
```

~~~properties
@Bean与@Component的区别:
1、@Component标注在类上,而@Bean标注在方法上
2、都可以注册为bean实例对象,被spring IOC容器托管
3、适用场景:@Component一般是用在自己定义的项目类中,而@Bean一般作用在引入的第三方组件类上。
~~~



##### 7.6 自动扫描标注注解的包

~~~xml
<!--在容器启动的时候,对标注注解的包进行自动扫描,扫描到以后自动进行注册到容器-->
<context:component-scan base-package="cn.hxzy"/>
~~~

### 8、Aop的简介

AOP是面向切面编程的意思,全称为Aspect Oriented Programing。

他是一种基于OOP之上的一种编程范式,弥补了OOP的不足,能更好的组织程序结构。

AOP可以把业务的功能步骤做成插拔式的组件,从而可以用这些组件定制新的功能,因此AOP可以提高业务的复用性,提高开发效率。

### 9、 代理模式

#### 9.1 角色分析

抽象角色:一般会使用接口或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色。代理真实角色后,我们一般会做一些附属操作,比如收房租等等。
客户:访问代理对象的人

#### 9.2 代理模式的好处

可以使真实角色的操作更加存粹,不用去关注一些公共的业务
公共业务就交给了代理角色,实现了业务的分工
公共业务发生扩展的时候,方面集中管理

#### 9.3 代码实现

定义接口

~~~java
/*
* 出租房屋
* */
public interface RentHouse {
    //出租房屋
    void czfw();
}
~~~

定义真实对象

~~~java
/*
* 房东类
* */
public class FangDong implements RentHouse{
    public void czfw() {
        System.out.println("出租房屋.....");
    }
}
~~~

定义代理对象

~~~java
/*
* 中介公司
* */
public class Proxy {
    /*代理类的属性:房东对象*/
    private FangDong fangDong;

    public Proxy(){}

    public Proxy(FangDong fangDong){
        this.fangDong=fangDong;
    }

    /*出租房屋*/
    public void czfw(){
        fangDong.czfw();
    }


    /*发广告*/
    public void fgg(){
        System.out.println("发出租房屋广告...");
    }
    /* 签订合同*/
    public void qht(){
        System.out.println("与房客签订租房合同....");
    }
    /*收费*/
    public void sf(){
        System.out.println("收取租房费用.....");
    }

}
~~~

### 10、Spring使用AOP

AOP的一些相关名词

切面(Aspect):横切关注点被模块化的特殊对象,是一个类

通知(Advice):切面必须要完成的工作,是类中的一个方法

切入点(pointCut):切面通知执行的位置

本身自己有一个SpringAOP框架,但实现的功能较基础。它整合了aspectj框架,完美的实现了AOP。

XML方式实现步骤:

#### 10.1、引入依赖

~~~xml
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>
~~~

#### 10.2、在核心配置文件中导入aspectj约束

~~~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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">  

</beans>
~~~

#### 10.3、定义日志类

~~~java
package cn.hxzy.log;

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

/*
* 日志类
* */
@Component(value = "afterLog")
public class LoggerProgram implements MethodBeforeAdvice {

    /*
    * 前置增强 before
    * */
    public void before(Method method, Object[] objects, Object target) throws Throwable {
        System.out.println("时间:"+new Date());
        System.out.println("目标对象方法:"+method.getName());
        for(Object o:objects){
            System.out.println("参数:"+o);
        }
        System.out.println("目标对象"+target.getClass().getName());
    }
}

~~~

增强处理的一些说明:

定义日志类,实现AfterReturningAdvice

returnValue 返回值

Method 要执行的目标对象的方法 method

Object[] 参数 args

Object 目标对象 target

target.getClass().getName() 目标对象的类的名称

method.getName() 方法的名称

#### 10.4、搭建项目结构

#### 10.5、在核心配置文件中添加AOP的配置

~~~xml
<!--进行AOP的XML配置-->
<aop:config>
    <!--定义切入点-->
    <aop:pointcut id="mypointcut" expression="execution(* cn.hxzy.dao.impl.UserMapperImpl.*(..))"/>
    <aop:advisor advice-ref="afterLog" pointcut-ref="mypointcut"/>
</aop:config>

~~~

前置增强:方法执行前进行的代码编织,实现接口:MethdBeforeAdvice

后置增强:方法执行后进行的代码编织   实现接口:AfterReturningAdvice

环绕增强:方法执行前后都进行代码编织,区别于前置+后置。把目标方法进行了围绕,无论是否发生异常都会被执行。实现接口:MethodInterceptor



```
切入点表达式:
execution(* cn.hxzy.dao.impl.*.*(..))
第一个* 表示的是方法任意的返回值
第二个* 表示任意的类
最后一个*表示的是任意的方法
```

<hr/>

论坛帖子:https://www.zhihu.com/question/24863332

### 11、使用注解来定义切面

好处:1、增加了代码的灵活度  2、减少了配置代码量

使用@AspectJ,首先要保证所用的JDK 是5.0或以上版本

@Aspect 标注这个类是一个切面

@Before("execution(* cn.hxzy.dao.Impl.UserDaoImpl.*(..))") 前置增强

@AfterReturning("execution(*cn.hxzy.dao.Impl.UserDaoImpl.*(..))") 后置增强

@AfterThrowing 异常通知, 在方法抛出异常之后

@Around 环绕通知, 围绕着方法执行

@After 最终增强



AOP应用场景:一般应用于针对核心业务的辅助功能,包括,事务处理,日志,系统安全,监控等场景中。使用横切代理的方式把辅助代码织入到核心方法之中去。
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值