## 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应用场景:一般应用于针对核心业务的辅助功能,包括,事务处理,日志,系统安全,监控等场景中。使用横切代理的方式把辅助代码织入到核心方法之中去。
07-26
208
11-17
452
07-10
1435
07-12
303
07-08
415
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交