在2023idea中实现SpringBoot的IoC和AOP的方法
一.代码介绍
(一)创建名为studentDao的接口
在com.example.demo包下创建一层dao包,在dao包下建一个名为studentDao的接口
package com.example.demo.dao; public interface studentDao { public void insertStudent(); }
(二)创建名为studentDaoImpl的类
在dao包下建一个impl包,在impl包下建一个名为studentDaoImpl的类
package com.example.demo.dao.impl; import com.example.demo.dao.studentDao; import org.springframework.stereotype.Repository; @Repository//Dao层一般用这个。表示的是当这个类被扫描到的时候,会自动创建该类的对象,把它装载到ioc容器当中供调用 public class studentDaoImpl implements studentDao { @Override public void insertStudent() { System.out.println("insertStudent被调用"); } }
(三)创建名为studentService的接口
在com.example.demo包下创建一层service包,在service包下建一个名为studentDao的接口
package com.example.demo.service; public interface studentService { public void saveStudent(); }
(四)创建名为studentServiceImpl的类
在service包下建一个impl包,在impl包下建一个名为studentServiceImpl的类
package com.example.demo.service.impl; import com.example.demo.dao.studentDao; import com.example.demo.service.studentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("studentService")//Service层中一般用这个。括号里面表示的是:id已经不是类名了,变成括号里面的studentService public class studentServiceImpl implements studentService { @Autowired//依赖注入中最常用的。表示的是会到容器中按照类型查找和装配进ioc容器 private com.example.demo.dao.studentDao studentDao; //应用Dao层的东西 @Override public void saveStudent() { studentDao.insertStudent(); } }
(五)创建名为MyAspect的类
在com.example.demo包下创建一层config包,在config包下建一个名为MyAspect的类
package com.example.demo.config; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Aspect //表示是一个切面类 //@Component//表示自动化实例对象 @Configuration//表示的是一个配置类,是用来替换配置文件的 public class MyAspect { @Before("execution(* *.*.demo.*.impl.studentDaoImpl.insertStudent(..))")//切点表达式的简略写法 *表示对一个或者多个包没有限制/也表示对访问修饰符和返回类型无所谓 函数名(..)中的..表示对函数中的参数没有限制 public void ad(){ } @Pointcut("execution(public void com.example.demo.dao.impl.studentDaoImpl.insertStudent())")//切点表达式 public void pointcut(){ } @Before("pointcut()")//切点表达式简化 public void before(){ System.out.println("我是前置通知,我要在insertStudent方法之前执行"); } }
(六)Demo1ApplicationTests
在test包下找到名为Demo1ApplicationTests的类
package com.example.demo; import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class Demo1ApplicationTests { /* @Autowired @Qualifier("studentService") 这两个可以用 @Resource(name="studentService")直接调换 */ @Resource(name="studentService")//自动装配 private com.example.demo.service.studentService studentService;//这里要用全限定类名来声明 @Autowired//依赖注入中最常用的。表示的是会到bean容器中按照类型查找和装配进ioc容器 private com.example.demo.dao.studentDao studentDao; @Test//测试类 void contextLoads() { } @Test public void testAnnoioc(){ studentService.saveStudent(); } @Test public void testaspect(){ studentDao.insertStudent(); } }
(七)导入spring-boot-starter-aop依赖
在pom.xml中导入spring-boot-starter-aop依赖
1.file->Settings->Plugins->搜索maven-search下载应用
2.Tools->Maven Search->搜索spring-boot-starter-aop任意版本复制粘贴到pom.xml中
3.去版本号
4.如图所示,一直刷新到出现Dependencies,其里面找到org.springframework.boot:spring-boot-starter-aop:3.0.2
Maven配置查看博主的上一条发布内容
(八)运行结果
二.IoC
(一)什么是IoC
IoC (Inversion of Control )即控制反转/反转控制。它是一种思想不是一个技术实现。描述的是:Java 开发领域对象的创建以及管理的问题。
例如:现有类 A 依赖于类 B
传统的开发方式 :往往是在类 A 中手动通过 new 关键字来 new 一个 B 的对象出来
使用 IoC 思想的开发方式 :不通过 new 关键字来创建对象,而是通过 IoC 容器(Spring 框架) 来帮助我们实例化对象。我们需要哪个对象,直接从 IoC 容器里面去取即可。
(二)为什么叫控制反转
控制 :指的是对象创建(实例化、管理)的权力
反转 :控制权交给外部环境(IoC 容器)
(三)IOC 解决了什么问题
IoC 的思想就是两方之间不互相依赖,由第三方容器来管理相关资源。这样有什么好处呢?
对象之间的耦合度或者说依赖程度降低;资源变的容易管理;
比如你用 Spring 容器提供的话很容易就可以实现一个单例。
(四)IoC 最常见以及最合理的实现方式叫做依赖注入(Dependency Injection,简称 DI)
(五)IoC注解 1.用于创建对象的
(1)@Repository:一般用于持久层(即Dao层)
作用:当这个类被扫描到的时候,会自动创建该类的对象,把它装载到ioc容器当中供调用(用于把当前类对象存入spring容器中)
属性:value 用于指定 bean 的 id。当我们不写时,他默认值是当前类名,且首字母改小写。 属性 value 当只有一个值时,value 书写可以省略。
如: 在IOC容器反射创建 AccountServiceImpl 的对象的时候。如果不传入参数,则表现层:
IAccountService as = (IAccountService) ac.getBean("accountServiceImpl");
也可以通过在类上面配置 @Component("accountService"),则表现层传入的参数应保持一样:
IAccountService as = (IAccountService) ac.getBean("accountService");
(2)@Component:表示自动实例化对象
(3)@Controller:一般用在表现层(即Controller层)
(4)@Service:一般用在业务层(即Service层)
以上三个注解他们的作用和属性与 Component 是一模一样的,因此可以混用。
2.用于注入数据的
(1)@Autowired----依赖注入中最常用的
作用:会到容器中按照类型查找和装配进IoC容器
(自动按照类型注入: 只要容器中有唯一的一个 bean 对象类型和要注入的数据类型匹配,就可以注入成功;如果 ioc 容器中没有任何 bean 的类型和要注入的变量类型匹配,则报错;如果 ioc 容器中有多个 bean 的类型和要注入的变量类型匹配,先根据 数据类型 (如:IAccountDao)找到范围,并在范围中在根据 变量的名称(如:accountDao)与 IOC 容器的 key 相匹配,最终注入。)
出现的位置: 可以是变量上,也可以是方法上
细节:在使用 Autowired 注解注入时,set 方法就不是必须的了。
(2)@Qualifier
作用:在按照类中注入的基础之上再按照 value 注入。
他在给类成员注入时不能单独(使用需和 Autowired 配合),但是在给方法参数注入时可以。
属性:value 用于指定 bean 的 id,无须考虑 Autowired,但是还需要写上 Autowired。eg:
@Autowired @Qualifier("accountDao1") private IAccountDao accountDao = null;
(3)@Resource
作用:直接按照 bean 的 id 注入。它可以独立使用。
属性:name 用于指定 bean 的 id。如:
@Resource(name = "accountDao1") private IAccountDao accountDao = null ;
以上三个注入只能注入其他的 bean 类型的数据,而基本类型和 String 类型无法使用上述注解实现。
另外,集合类型的注入只能通过 XML 来实现。
(4)@Value
作用:用于注入基本类型和 String 类型的数据
属性:value 用于指定数据的值。
它可以使用 spring 中的 SpEl(也就是 spring 的 el 表达式),SpEl的写法也是 ${表达式}
3.
用于改变作用范围的 @Scope
作用:用于指定bean的作用范围
属性:value 指定范围的取值。常用取值:singleton, prototype@Scope(“prototype”)
在类上使用,如:
@Component("accountService") @Scope("prototype") public class AccountServiceImpl implements IAccountService {...}
4.和生命周期相关
他们的作用就和在 bean 标签中使用 init-method 和 destroy-method 的作用是一样的
(1)@PostConstruct
作用:用于指定初始化方法
(2)@PreDestroy
作用:用于指定销毁方法
@PostConstruct public void init(){ System.out.println("初始化"); } @PreDestroy public void destroy(){ System.out.println("销毁方法Service");//这里单例对象需要手动关闭才会执行该方法 }
三.AOP
(一)什么是AOP
AOP:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(二)AOP 的作用及其优势
作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:减少重复代码,提高开发效率,并且便于维护
(三)AOP 的底层实现
AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
(四)常用的动态代理技术
JDK 代理 : 基于接口的动态代理技术
cglib 代理:基于父类的动态代理技术
(五)AOP相关概念
1.Target(目标对象):代理的目标对象 (织入 Advice
的目标对象.。)
2.Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类
3.Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。(表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。)
4.Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。(表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。)
5.Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知 (Advice 定义了在 Pointcut
里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。)
6.Aspect(切面):是切入点和通知的结合( Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。)
7.Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。 安装的过程(将 Aspect
和其他对象连接起来, 并创建 Advice
d object 的过程)
(六)AOP注解
1.@Aspect
位置:类定义上方
作用:设置当前类为切面类
格式:
@Aspect public class AopAdvice { }
说明:一个beans标签中可以配置多个aop:config标签
2.@Pointcut
位置:方法定义上方
作用:使用当前方法名作为切入点引用名称
格式:
@Pointcut("execution(* *(..))") public void pt() { }
说明:被修饰的方法忽略其业务功能,格式设定为无参无返回值的方法,方法体内空实现(非抽象)
3.@Before
位置:方法定义上方
作用:标注当前方法作为前置通知
格式:
@Before("pt()") public void before(){ }
无特殊参数
4.@After
位置:方法定义上方
作用:标注当前方法作为后置通知
格式:
@After("pt()") public void after(){ }
无特殊参数
5.@AfterReturning
位置:方法定义上方
作用:标注当前方法作为返回后通知
格式:
@AfterReturning(value="pt()",returning = "ret") public void afterReturning(Object ret) { }
特殊参数:
returning :设定使用通知方法参数接收返回值的变量名
6.@AfterThrowing
位置:方法定义上方
作用:标注当前方法作为异常后通知
格式:
@AfterThrowing(value="pt()",throwing = "t") public void afterThrowing(Throwable t){ }
特殊参数:
throwing :设定使用通知方法参数接收原始方法中抛出的异常对象名
7.@Around
位置:方法定义上方
作用:标注当前方法作为环绕通知
格式:
@Around("pt()") public Object around(ProceedingJoinPoint pjp) throws Throwable { Object ret = pjp.proceed(); return ret; }
无特殊参数
到此这篇关于在2023idea中如何实现SpringBoot的IoC和AOP的文章就介绍到这了,更多相关idea中实现SpringBoot的IoC和AOP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java使用System.currentTimeMillis()方法计算程序运行时间的示例代码
System.currentTimeMillis() 方法的返回类型为 long ,表示毫秒为单位的当前时间,文中通过示例代码介绍了计算 String 类型与 StringBuilder 类型拼接字符串的耗时情况,对Java计算程序运行时间相关知识感兴趣的朋友一起看看吧2022-03-03Spring配置文件解析之BeanDefinitionParserDelegate详解
这篇文章主要介绍了Spring配置文件解析之BeanDefinitionParserDelegate详解,对于Spring的配置文件的解析处理操作是在BeanDefinitionParserDelegate中进行处理操作,接下来我们简单介绍一下BeanDefinitionParserDelegate所做的处理操作,需要的朋友可以参考下2024-02-02java.lang.NoClassDefFoundError错误的原因及解决方法
这篇文章主要给大家介绍了关于java.lang.NoClassDefFoundError错误的原因及解决的相关资料,java.lang.NoClassDefFoundError是Java虚拟机在运行时无法找到特定类的错误,需要的朋友可以参考下2023-10-10
最新评论