热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring5框架学习总结一【IOC、AOP】

目录一、Spring概念入门案例二、IOC容器1.IOC底层原理2.IOC接口(BeanFactor)3.IOC操作Bean管理(基于xm

目录

  • 一、Spring概念
    • 入门案例
  • 二、IOC容器
    • 1. IOC底层原理
    • 2. IOC接口(BeanFactor)
    • 3. IOC操作Bean管理(基于xml)
      • 3.1 普通Bean
      • 3.2 工厂Bean
      • 3.3 Bean的作用域
      • 3.4 Bean的声明周期
      • 3.5 Bean的自动装配
      • 3.6 引入外部属性文件
    • 4. IOC操作Bean管理(基于注解)
      • 1. 注解创建对象
      • 2. 注解属性注入
      • 3. 纯注解开发
  • 三、Aop
    • 1. Aop概念
    • 2. Aop底层原理
    • 3. Aop在Spring框架中操作
      • 3.1 准备工作
      • 3.2 基于AspectJ注解
      • 3.3 基于AspectJ配置文件




一、Spring概念

① Spring是轻量级的开源的JavaEE框架;
② Spring可以决解企业开发的复杂性;
③ Spring的两个核心部分:IOC 和 Aop;
(1)IOC:控制反转,把创建对象过程交给Spring进行管理。
(2)Aop:面向切面,不修改代码
④ Spring特点:
(1)方便解耦,简化开发;
(2)Aop编程的支持;
(3)方便程序的测试;
(4)方便整合其他框架一起使用;
(5)方便进行事物的操作;
(6)降低API开发难度;


入门案例

(1)下载Spring5的框架
下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring/
在这里插入图片描述
(2)使用Idea创建一个普通Java工程
在这里插入图片描述

(3)导入Spring5相关jar包

1.直接从下载好的框架中复制进去;
在这里插入图片描述
2.选择导入项目
在这里插入图片描述

(4)创建普通的类,普通方法
在这里插入图片描述
(5)创建Spring配置文件,在配置文件配置创建对象
Spring配置文件使用.xml格式;
在这里插入图片描述

(6)测试代码
在这里插入图片描述



二、IOC容器

1. IOC底层原理


什么是IOC:
① 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理;
② 使用IOC目的:降低耦合度;
底层原理:
① xml解析、工厂模式、反射;

// 第一步&#xff1a;xml配置文件&#xff0c;配置创建对象<!--配置User对象创建--><bean id&#61;"user" class&#61;"com.nzs.spring5.User"></bean>
// 第二步&#xff1a;有servise类和dao类&#xff0c;创建工厂
class UserFactory{public static UserDao getDao(){String classValue &#61; class属性值; // xml解析Class myclass &#61; Class.forName(classValue);// 通过反射创建对象return (UserDao)myclass.newInstance();}
}


2. IOC接口&#xff08;BeanFactor&#xff09;


① IOC思想基于IOC容器完成&#xff0c;IOC容器底层就是对象工厂&#xff1b;
② Spring提供IOC容器实现的两种方式&#xff1a;&#xff08;两个接口&#xff09;

&#xff08;1&#xff09;BeanFactory&#xff1a;是Spring内部使用的接口&#xff0c;不提供开发人员使用。加载配置文件时候不会创建对象&#xff0c;在获取对象(使用)才会去创建对象。

&#xff08;2&#xff09;ApplicationContext&#xff1a;是BeanFactory接口的子接口&#xff0c;提供了更多更强大的功能&#xff0c;一般由开发人员使用。加载配置文件时就会把配置文件对象进行创建。
&#xff08;3&#xff09;ApplicationContext接口的实现类&#xff1a;ClassPathXmlApplicationContext (项目路径)和FileSystemXmlApplicationContext(盘符路径)。



3. IOC操作Bean管理&#xff08;基于xml&#xff09;

什么是Bean管理&#xff1a; Bean管理指两个操作&#xff0c;Spring创建对象 和 Spring注入属性。
Bean管理的两种方式&#xff1a; 基于xml配置文件方式实现&#xff0c;基于注解方式实现。
两种Bean&#xff1a;普通bean&#xff0c;工厂Bean
普通Bean&#xff1a;在配置文件中定义Bean类型就是返回类型&#xff1b;
工厂Bean&#xff1a;在配置文件中定义Bean类型可以和返回值类型不一样&#xff1b;

3.1 普通Bean


1. 基于xml方式创建对象&#xff1a;
① 默认执行无参的构造方法&#xff1b;
2. 基于xml方式注入属性&#xff1a;
① DI&#xff1a;依赖注入&#xff0c;就是注入属性&#xff1b;
第一种&#xff1a;使用set方法进行注入&#xff1b;

1.创建属性、创建属性set方法;
2.在spring配置文件中配置对象创建&#xff0c;配置属性注入&#xff1b;

<bean id&#61;"user" class&#61;"com.nzs.spring5.User"><property name&#61;"myname" value&#61;"宁"></property></bean>

第二种&#xff1a;有参构造进行注入&#xff1b;

1.声明属性、声明有参构造方法;
2.在spring配置文件中配置对象创建&#xff0c;配置属性注入&#xff1b;

<bean id&#61;"user" class&#61;"com.nzs.spring5.User"><constructor-arg name&#61;"myname" value&#61;"宁"></constructor-arg></bean>

第三种&#xff1a;p命名空间进行注入&#xff1b;

添加&#xff1a;xmlns:p&#61;"http://www.springframework.org/schema/p"
<bean id&#61;"user" class&#61;"com.nzs.spring5.User" p:myname&#61;"宁"></bean>

3. 基于xml方式注入其他类型的属性&#xff1a;
自变量

1.null值&#xff1a;
在这里插入图片描述
2.属性值中包含特殊字符&#xff1a;
在这里插入图片描述

注入属性 - 外部bean

1.创建两个类&#xff0c;service类和dao类&#xff1b;
2.在service类中调用dao中的方法&#xff1b;
在这里插入图片描述
3.在spring配置文件中进行配置&#xff1b;
在这里插入图片描述

注入属性 - 内部bean

1.一对多关系&#xff1a;部门与员工&#xff1b;
2.在实体类之间表示一对多的关系&#xff1b;
3.在spring配置文件中进行配置&#xff1b;
在这里插入图片描述

注入属性 - 级联赋值
在这里插入图片描述
注入数组类型属性
在这里插入图片描述
注入List集合类型属性
在这里插入图片描述
注入Map集合类型属性
在这里插入图片描述
注入Set集合类型属性
在这里插入图片描述
4. 在集合里面设置对象类型值&#xff1a;
在这里插入图片描述
5. 把集合注入部分提取出来&#xff1a;

(1) 在spring配置文件中引入名称空间util&#xff1b;
在这里插入图片描述
&#xff08;2&#xff09;使用util标签完成list集合注入提取
在这里插入图片描述



3.2 工厂Bean

步骤&#xff1a;
&#xff08;1&#xff09;创建类&#xff0c;让这个类作为工厂bean&#xff0c;实现接口FactoryBean&#xff1b;
&#xff08;2&#xff09;实现接口里面的方法&#xff0c;在实现的方法中返回自己想要的Bean类型&#xff1b;

3.3 Bean的作用域


1. 单实例和多实例&#xff1a;
① 默认情况下是单实例&#xff0c;通过设置bean标签中的scope属性来设置单实例和多实例&#xff0c;sinleton为单实例&#xff0c;prototype为多实例。
② scope为sinleton时&#xff0c;加载配置文件时就会创建单实例对象&#xff1b;scope为prototype时&#xff0c;在调用getBean方法时才会创建多实例对象。


3.4 Bean的声明周期


① 通过构造器创建bean实例&#xff08;无参构造&#xff09;&#xff1b;
② 为bean的属性设置值 或者 对其他bean引用&#xff08;调用set方法&#xff09;&#xff1b;
③ 初始化之前&#xff0c;把bean实例传递bean后置处理器的方法postProcessBeforeInitialization&#xff1b;
④ 调用bean的初始化方法&#xff08;需要进行配置初始化方法&#xff1a;init-method属性&#xff09;&#xff1b;
⑤ 初始化之后&#xff0c;把bean实例传递bean后置处理器方法postProcessAfterInitialization&#xff1b;
⑥ bean可以使用了&#xff1b;
⑦ 当容器关闭时&#xff0c;调用bean的销毁方法&#xff08;需要进行配置销毁方法&#xff1a;destroy-method属性 &#43; 手动调用context.close()&#xff09;;

配置后置处理器&#xff1a;在这里插入图片描述
在这里插入图片描述


3.5 Bean的自动装配

根据指定的装配规则(属性名称或者属性类型)&#xff0c;spring自动将匹配的属性进行注入。

① 根据属性名称注入(byName)&#xff1a;注入值bean的id值和类型属性值一样&#xff1b;
② 根据属性类型注入(byType)&#xff1a;多个相同类型bean就会出错&#xff1b;


3.6 引入外部属性文件

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

4. IOC操作Bean管理&#xff08;基于注解&#xff09;


① 注解可以作用在类、方法、属性上面&#xff1b;
② 注解的作用&#xff1a;简化xml配置


1. 注解创建对象

注&#xff1a;四个注解的功能都是一样的&#xff0c;都可以用来创建对象。
&#64;Component&#xff0c;&#64;Service&#xff0c;&#64;Controll&#xff0c;&#64;Repository

步骤&#xff1a;
① 引入依赖 - spring-aop-5.2.6.RELEASE.jar&#xff1b;
② 开启组件扫描&#xff1b;
在这里插入图片描述
③ 使用注解创建对象

// value值可以不写&#xff0c;默认值为类名首字母小写
&#64;Component(value &#61; "userService") // 等价与 &#61;
public class UserService {private String uName;public void add(){System.out.println("service add -----------------");>}
}


2. 注解属性注入

&#64;Autowired&#xff1a;根据属性类型注入&#xff1b;
&#64;Qualifier&#xff1a;根据属性名称注入&#xff0c;和&#64;Autowired一起使用(以防同一个类型有多个对象&#xff0c;而找不到)&#xff1b;
在这里插入图片描述
&#64;Resource&#xff1a;可根据类型注入&#xff0c;也可根据名称注入&#xff1b;
在这里插入图片描述
&#64;Value&#xff1a;注入普通数据类型&#xff1b;
在这里插入图片描述

3. 纯注解开发


① 创建配置类&#xff0c;代替xml配置文件&#xff1b;

&#64;Configuration //作为配置类&#xff0c;代替xml配置文件
&#64;ComponentScan(basePackages &#61; {"com.nzs.spring5"})// 替换
public class SpringConfig {
}

② 测试

&#64;Testpublic void test2(){// 加载配置类ApplicationContext context &#61; new AnnotationConfigApplicationContext(SpringConfig.class);UserService userService &#61; context.getBean("userService", UserService.class);userService.add();}




三、Aop

1. Aop概念


① 面向切面编程&#xff0c;利用AOP可以对业务逻辑的各个部分进行隔离&#xff0c;从而使得业务逻辑各个部分之间的耦合度降低&#xff0c;提高程序的可重用性&#xff0c;同时提高开发效率。
Aop术语&#xff1a;
① 连接点&#xff1a;类里面哪些方法可以被增强&#xff0c;这些方法称为连接点&#xff1b;
② 切入点&#xff1a;实际被增强的方法&#xff0c;称为切入点&#xff1b;
③ 通知(增强)&#xff1a;实际增强的逻辑部分称为通知(5种)&#xff1b;
④ 切面&#xff1a;把通知应用到切入点过程&#xff1b;
5种通知&#xff1a;
① 前置通知&#xff1a;
② 后置通知&#xff1a;
③ 环绕通知&#xff1a;
④ 异常通知&#xff1a;
⑤ 最终通知&#xff1a;


2. Aop底层原理


Aop底层使用动态代理两种方法&#xff1a;
① 有接口&#xff0c;使用JDK动态代理&#xff1b;创建接口类代理对象&#xff0c;增强类的方法。
② 没有接口&#xff0c;使用CGLIB动态代理&#xff1b;创建子类的代理对象&#xff0c;增强类的方法。
JDK动态代理&#xff1a;
① 使用Proxy类里面的方法创建代理对象。调用newProxyInstance&#xff1b;
第一个参数&#xff1a;类加载器&#xff1b;
第二个参数&#xff1a;增强方法所在的类&#xff0c;这个类实现的接口&#xff0c;支持多个接口&#xff1b;
第三个参数&#xff1a;实现这个接口InvocationHandler&#xff0c;创建代理对象&#xff0c;写增强方法&#xff1b;
② 实现代码&#xff1a;创建接口 ----> 创建类实现接口 ----> 使用Proxy类创建接口代理对象&#xff1b;

public class JDKProxy {public static void main(String []args){// 创建接口实现类代理对象Class[] interfaces &#61; {UserDao.class};UserDaoImpl temp_userDao &#61; new UserDaoImpl();UserDao userDao &#61; (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(temp_userDao));userDao .update("战胜");}
}class UserDaoProxy implements InvocationHandler{private Object obj;public UserDaoProxy(Object obj){this.obj &#61; obj;}&#64;Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在方法之前 --增强System.out.println("在方法之前&#xff1a;" &#43; method.getName() &#43; "传递参数&#xff1a;"&#43; Arrays.toString(args));// 被增强的方法执行Object res &#61; method.invoke(obj,args);// 在方法之后 -- 增强System.out.println("在方法之后 -- 增强-");return res;}
}

在这里插入图片描述


3. Aop在Spring框架中操作


3.1 准备工作

Spring框架一般都是基于AspectJ实现AOP操作&#xff1b;AspectJ不是Sprnig组成部分&#xff0c;独立于AOP框架&#xff1b;
两种方式&#xff1a;基于xml配置文件实现、基于注解方式实现。
在这里插入图片描述

切入点表达式&#xff1a;
① 切入点作用&#xff1a;知道对哪个类里面的哪个方法进行增强&#xff1b;
② 语法结构&#xff1a;execution([权限修饰符][返回值类型][类全路径][方法名称]([参数列表]))&#xff1b;

// 举例1&#xff1a;对com.nzs.dao.BookDao类里面的add方法进行增强&#xff1b;
execution(* com.nzs.dao.BookDao.add(..))
// 举例2&#xff1a;对com.nzs.dao.BookDao类里面的所有方法进行增强&#xff1b;
execution(* com.nzs.dao.BookDao.*(..))
// 举例3&#xff1a;对com.nzs.dao包下所有类中的所有方法进行增强&#xff1b;
execution(* com.nzs.dao.*.*(..))


3.2 基于AspectJ注解


① 创建类&#xff0c;定义需要增强的方法&#xff1b;
② 创建增强类(编写增强逻辑)&#xff1b;
③ 进行通知配置&#xff1b;
&#xff08;1&#xff09;在配置文件中开启注解扫描&#xff1b;
&#xff08;2&#xff09;使用注解创建User和UserProxy对象&#xff1b;
&#xff08;3&#xff09;在增强类添加注解&#64;Aspect&#xff1b;
&#xff08;4&#xff09;在spring配置文件中开启生成代理对象&#xff1b;
④ 配置不同类型的通知&#xff0c;在增强类里面&#xff0c;在作为通知方法上添加通知类型注解&#xff0c;使用切入表达式配置&#xff1b;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
执行user.add()方法
在这里插入图片描述

当多个增强类对同一个方法进行增强时&#xff0c;可以在增强类上添加注解&#64;Order(值)来设置执行顺序。

不同通知&#xff1a;
① &#64;Before&#xff1a;前置通知
② &#64;AfterReturning&#xff1a;返回通知
③ &#64;After&#xff1a;最终通知
④ &#64;AfterThrowing&#xff1a;异常通知
⑤ &#64;Around&#xff1a;环绕通知
相同切入点抽取&#xff1a;
在这里插入图片描述


3.3 基于AspectJ配置文件


① 创建增强类 和 被增强类&#xff0c;声明方法&#xff1b;
② 在spring配置文件中创建两个类对象&#xff1b;
③ 在spring配置文件中配置切入点&#xff1b;

<!-- 创建两个类对象 -->
<bean id&#61;"user" class&#61;"com.nzs.spring5.aopanon.User"></bean>
<bean id&#61;"userProxy" class&#61;"com.nzs.spring5.aopanon.UserProxy"></bean>
<!-- 配置aop增强 -->
<aop:config><!--切入点--><aop:pointcut id&#61;"p1" expression&#61;"execution(* com.nzs.spring5.aopanon.User.add(..))"/><!--切面--><aop:aspect ref&#61;"userProxy"><!--增强作用在具体的方法上--><aop:before method&#61;"before" pointcut-ref&#61;"p1"/></aop:aspect>
</aop:config>



四、JdbcTemplate
五、事物管理
六、Spring5新特性
后续内容&#xff1a;Spring5框架学习总结【JdbcTemplate、事物管理、Spring5新特性】


推荐阅读
author-avatar
小白
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有