初试spring

mac2026-03-31  5

初始spring框架

最近接触到spring框架,今天利用小黄鸭调试法来理一下个人理解.内容主要分为一下三点 1 spring解决的问题 2 ioc 3 aop

1 spring 解决的问题

利用ioc核心思想,整合各大优秀框架,减轻了企业开发的难度.

2 ioc

2.1 ioc Inverse of Control(控制反转)

1 实例化 2 依赖注入

ioc:将原本在程序中手动创建对象的控制权,交由Spring框架来管理。

简单的说,最初我们创建对象是通过手动 Obeject o=new Object(),控制权在我们手中.利用ioc的话,我们只需要声明 Obejct o,o=new Object()的步骤交给spring容器.这种控制权从我们手中转交到spring容器中,称之为控制反转(ioc).

总的来说spring ioc需要做两件事 1 实例化对象(new Object), 2 赋值(o =xx),又称之为依赖注入.

2.2 配置文件

配置文件:将对象之间的关系传递给spring框架.

刚刚我们简单了解了一下ioc思想,但是这里有个很重要的问题,spring如何知道对象之间的关系呢?简单的说 Object o;o该赋什么值spring并不清楚.只有我们才清楚,这时就需要我们告诉spring对象关系,或者说依赖关系.这个时候,我们就需要配置文件了,通过配置将对象之间的关系传递给spring.这样spring就能实例化对象和注入依赖.

我先简单贴一些代码,配置一下文件 1 先通过idea 和maven创建项目,通过maven导入spring框架.在项目main目录下创建resources目录,maven刷新一下,识别目录.然后创建spring的xml配置文件. 2 创建一些dao接口,实现类 service接口,实现类 以及main方法,大致结构如下: 3 具体类的代码 userDao 接口

package com.woniu.spring.ioc.dao; /* 创建一个接口,用于实现 */ public interface UserDao { //声明方法 public void find(); }

实现类

package com.woniu.spring.ioc.dao.impl; import com.woniu.spring.ioc.dao.UserDao; //实现类 public class UserDaoImpl implements UserDao { @Override public void find() { System.out.println("调用find方法"); } }

userservice接口

package com.woniu.spring.ioc.service; //接口 public interface UserService { public void find(); }

实现类:旧写法,直接new 对象,赋值然后调用方法

package com.woniu.spring.ioc.service.impl; import com.woniu.spring.ioc.dao.UserDao; import com.woniu.spring.ioc.dao.impl.UserDaoImpl; import com.woniu.spring.ioc.service.UserService; public class UserServiceImpl implements UserService { //以前的写法,直接new对象,然后调用方法 UserDao userDao=new UserDaoImpl(); @Override public void find() { userDao.find(); } }

主方法:旧写法,直接new 对象,赋值然后调用方法

package com.woniu.spring.ioc; import com.woniu.spring.ioc.service.UserService; import com.woniu.spring.ioc.service.impl.UserServiceImpl; public class App { public static void main( String[] args ) { //以前写法 UserService userService=new UserServiceImpl(); userService.find(); } }

接下来我们用ioc的写法: userserviceiml类:

package com.woniu.spring.ioc.service.impl; import com.woniu.spring.ioc.dao.UserDao; import com.woniu.spring.ioc.dao.impl.UserDaoImpl; import com.woniu.spring.ioc.service.UserService; public class UserServiceImpl implements UserService { //以前的写法,直接new对象,然后调用方法 //UserDao userDao=new UserDaoImpl(); //ioc写法,不赋值,只声明,值由spring容器注入 UserDao userDao; //需要添加setter方法,spring容器通过调用set方法注入依赖 public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void find() { userDao.find(); } }

然后在resources下面创建xml文件,并配置.上文提到ioc主要做两件事 :实例化和注入依赖(赋值); 配置文件就是告诉spring实例化哪个类,以及为哪个类的哪个成员属性注入依赖(赋值).

<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"> <!-- 创建bean,spring中一个bean就是一个实例.牢记创建实例和注入依赖两个步骤--> <!-- 在userServiceiml类中需要调用userdaoiml,所以我们先创建userdaoiml的实例--> <!-- bean格式如下 id是标记,方便后续引用该实例,class是类路径--> <bean id="userDao" class="com.woniu.spring.ioc.dao.impl.UserDaoImpl"/> <!-- 接下来是实例化userserviceiml 并为其usrdao成员属性注入依赖--> <bean id="userService" class="com.woniu.spring.ioc.service.impl.UserServiceImpl"> <!-- 注入依赖,通过property标签 name属性会匹配类中的set方法 ref通过id名引用上面实例的bean,通过set方法注入依赖--> <property name="userDao" ref="userDao"/> </bean> <!-- 这样,我们就完成了简单的xml配置,当然注入依赖和配置方法还有其他的方式,后续再说--> </beans>

主方法解析配置文件

package com.woniu.spring.ioc; import com.woniu.spring.ioc.service.UserService; import com.woniu.spring.ioc.service.impl.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main( String[] args ) { //以前写法 /* UserService userService=new UserServiceImpl(); userService.find();*/ //ioc写法 //通过解析xml配置文件创建一个applicationContext容器,容器中保存着bean实例, ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //通过getbean方法获取实例,然后调用方法 //注意事项,getbean参数是 接口.class ,name可以不用,xml配置的是对应接口的实现类 UserService userService = ac.getBean("userService", UserService.class); //利用多态性的动态绑定,调用实现类的方法 userService.find(); } }

通过上述代码我们完成了一个ioc的例子,spring容器帮我们完成了实例化和依赖注入.我们只需要通过配置文件告诉spring容器对象之间的关系即可.

2.3 配置文件多种配置方式

单独分了一篇出来,https://blog.csdn.net/xiaobozhi1993/article/details/102870163

2.4 ioc优势

1 解耦,降低了类与类的耦合度 以上述代码中UserserviceIml中成员属性UserDao usedao为例,不直接初始对象,编译时无法得知具体的引用是什么,降低了两个类之间的联系.只有运行时,spring容器注入依赖,利用动态绑定才能确定具体的实现类是什么.

2 增加代码的灵活性,易于维护 userserviceiml类中只声明成员属性UserDao userdao,它是一个接口,具体的实现类是通过xml配置文件注入的.如果哪天需要更新功能,只需要实现同样的接口,重写一下方法,xml注入新的实现类即可更换功能,

3 AOP

1 个人理解 只说一下个人理解,技术都是为了更方便,更好用,提高程序员效率.现在我有一百个类,每个类5个方法,每个方法开始执行前都想打印输出一句话,“方法执行了”.这种重复价值肯定是需要被干掉的,于是有大佬就想有没有什么办法能够自动的在需要的地方添加需要的方法,aop就是干这个的.它能够在指定地方(比如方法前后)加入指定的功能.此时可以类比web应用过滤器器filter,类似所有请求设置字符编码. 2 术语 大概知道了aop是做什么的 ,接下来就来说一下术语,围绕指定地方和指定功能这两个点来理解1

1 通知(advice) 就是指定功能,比如打印日志等。2 连接点(join point) aop运行添加通知的地方,比如方法前后3 切入点(Pointcut) 我们筛选出来的连接点,某些类的某些方法4.切面(Aspect) 切入点和通知组装起来就是切面.5.目标(target) 需要切入的类6.织入(weaving) 把切面应用到目标对象来创建新的代理对象的过程

3 如何配置使用 导包

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

配置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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置路径,扫描所有类文件--> <context:component-scan base-package="com.woniu.spring"/> <!-- 自动生成代理--> <aop:aspectj-autoproxy/> </beans>

创建切面类

package com.woniu.spring; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; //添加注解,成为bean @Component //添加注解,成为切面 @Aspect public class AspectDemo { //前置通知,方法前执行.execution是aop特有表达式,匹配所有类的所有方法 @Before("execution(* com.woniu.spring.service.*.*(..))") public void befor(JoinPoint jpt){ System.out.println("方法开始了"); } @AfterReturning("execution(* com.woniu.spring.service.*.*(..))") public void afReturn(JoinPoint jpt){ System.out.println("方法正常执行返回"); } } package com.woniu.spring; import com.woniu.spring.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) { ApplicationContext ac =new ClassPathXmlApplicationContext("aop.xml"); UserService userService = ac.getBean(UserService.class); userService.find(); //通过AnnotationConfigApplicationContext解析ConfigContext配置类文件 /*ApplicationContext ac=new AnnotationConfigApplicationContext(ConfigContext.class); UserService userService=ac.getBean(UserService.class); userService.find();*/ } }
最新回复(0)