【SSM】 Spring 笔记

目录


一、搭建Spring环境

下载 jar 包

① spring-aop.jar (开发AOP特性时需要的 jar)
② spring-beans.jar (管理Bean的 jar)
③ spring-context.jar (处理spring上下文的 jar)
④ spring-core.jar (spring核心 jar)
⑤ spring-expression.jar (spring表达式 jar)
⑥ commons-logging.jar (三方提供,日志 jar)


二、编写配置文件

为了编写时有一些提示或自动生成一些配置信息,需要增加插件:spring tool suite (sts)

新建名为 applicationContext.xml 的 Spring Bean Configuration File

① 在配置文件 applicationContext.xml 中加入:
<!-- 该文件中产生的所有对象,被Spring放入了一个称之为SpringIOC容器的地方 -->
<!-- id:唯一标识符               class:指定类型 -->
<bean id="student" class="org.lanqiao.entity.Student">
	<!--
		property:class所代表的类的属性
		name:属性名
		value:属性值 
	 -->
	<property name="stuNo" value="1"></property>
	<property name="stuName" value="ls"></property>
	<property name="stuAge" value="19"></property>
</bean>
② 测试:
//Spring上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//执行从SpringIOC容器中获取一个id为student的对象
Student student = (Student)context.getBean("student");
System.out.println(student.toString());
③ 运行结果:

在这里插入图片描述


三、开发Spring程序 (IOC)

IOC (控制反转) 也可以称之为DI (依赖注入):

控制反转:将 创建对象,属性值的方式 进行了翻转,从 new,setXxx() 翻转为了从 SpringIOC容器 getBean()

依赖注入:将属性值注入给了属性,将属性注入给了Bean,将Bean注入给了IOC容器。

总结:IOC/DI 无论需要什么对象,都可以直接去SpringIOC容器中获取,而不需要自己操作 (new / setXxx)

IOC容器赋值

①如果是 简单类型 ,使用 value ;
②如果是 对象类型 ,ref = "需要引用的id值" ,因此实现了 对象与对象之间的依赖关系

context.getBean(需要获取的bean的id值)


四、依赖注入的三种方式:

(1) 通过set方式赋值

【 通过setXxx() 赋值,默认使用的set方法;依赖注入底层时通过 反射 实现的 】
① appicationContext.xml 中添加 Bean
<bean id="teacher" class="org.lanqiao.entity.Teacher">
	<!-- 通过set方式赋值 -->
	<property name="name" value="zs"></property>
	<property name="age" value="20"></property>
</bean>

<bean id="course" class="org.lanqiao.entity.Course">
	<!-- 通过set方式赋值 -->
	<property name="courseName" value="java"></property>
	<property name="courseHour" value="200"></property>
	<!-- 将teacher对象注入到course对象中 -->
	<property name="teacher" ref="teacher"></property>
</bean>
② 测试代码:
public static void testDI() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	Course course = (Course)context.getBean("course");
	course.showInfo();
}
③ 运行结果:

在这里插入图片描述


(2) 通过构造器赋值

【通过  构造方法  赋值】
① appicationContext.xml 中添加 Bean
<bean id="teacher" class="org.lanqiao.entity.Teacher">
	<!-- 通过构造器赋值 -->
	<constructor-arg value="李四"></constructor-arg>
	<constructor-arg value="30"></constructor-arg>
</bean>

<bean id="course" class="org.lanqiao.entity.Course">
	<!-- 通过构造器赋值 (参数顺序不一致,可通过index,name,type等指定参数)-->
	<constructor-arg value="C语言"></constructor-arg>
	<constructor-arg value="150"></constructor-arg>
	<constructor-arg ref="teacher"></constructor-arg>
</bean>
② 测试代码:
public static void testDI() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	Course course = (Course)context.getBean("course");
	course.showInfo();
}
③ 运行结果:

在这里插入图片描述


(3) p命名空间注入

【引入p命名空间】

在这里插入图片描述
也可以直接在 appicationContext.xml 的头文件中添加:

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

在这里插入图片描述

① appicationContext.xml 中添加 Bean
<bean id="teacher" class="org.lanqiao.entity.Teacher" p:age="25" p:name="王五">
</bean>

<bean id="course" class="org.lanqiao.entity.Course" p:courseName="Python" p:courseHour="120" p:teacher-ref="teacher">
</bean>
② 测试代码:
public static void testDI() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	Course course = (Course)context.getBean("course");
	course.showInfo();
}
③ 运行结果:

在这里插入图片描述


五、各种集合类型的属性注入

【set,list,数组各自都有自己的标签< set >< list >< array > ,但也可以混着用,例如set也可以用< list >< array >
① 在 appicationContext.xml 中加入:
<!-- 各种集合类型的属性注入 -->
	<bean id="CollectionDemo" class="org.lanqiao.entity.CollectionDemo">
		<!-- 列表类型 -->
		<property name="listElement">
			<list>
				<value>java1</value>
				<value>html1</value>
				<value>php1</value>
			</list>
		</property>
		
		<!-- 数组类型 -->
		<property name="arrayElement">
			<array>
				<value>java2</value>
				<value>html2</value>
				<value>php2</value>
			</array>
		</property>
		
		<!-- set 类型 -->
		<property name="setElement">
			<set>
				<value>java3</value>
				<value>html3</value>
				<value>php3</value>
			</set>
		</property>
		
		<!-- map 类型 -->
		<property name="mapElement">
			<map>
				<entry>
					<key>	
						<value>111</value>
					</key>
					<value>java4</value>
				</entry>
				<entry>
					<key>	
						<value>222</value>
					</key>
					<value>html4</value>
				</entry>
				<entry>
					<key>	
						<value>333</value>
					</key>
					<value>php4</value>
				</entry>
			</map>
		</property>
		
		<!-- properties 类型 -->
		<property name="propertiesElement">
			<props>
				<prop key="555">java5</prop>
				<prop key="666">html5</prop>
				<prop key="777">php5</prop>
			</props>
		</property>
	</bean>
② 测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
CollectionDemo collectionDemo = (CollectionDemo)context.getBean("CollectionDemo");
System.out.println(collectionDemo.toString());
③ 运行结果:

在这里插入图片描述


六、自动装配 (只适用于 ref 类型)

【自动装配虽然可以减少代码量,但是会降低程序的可读性,使用时需要谨慎。】

(1) 测试自动装配

① 在 appicationContext.xml 中加入:
<bean id="teacher" class="org.lanqiao.entity.Teacher" p:age="25" p:name="王五">
</bean>

<!-- byName 按id自动装配course的teacher对象-->
<bean id="course" class="org.lanqiao.entity.Course" autowire="byName">
	<property name="courseName" value="zs"></property>
	<property name="courseHour" value="20"></property>
</bean>
② 测试代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Course course = (Course)context.getBean("course");
course.showInfo();
③ 运行结果

在这里插入图片描述


(2) 自动装配的几种常见类型:

① byName: 自动寻找:其他bean的id值=该Course类的属性名(例:course 中的 teacher)

② byType: 其他bean的类型(class) 是否与 该Course类的ref属性类型一致 (注意,此种方式 必须满足:当前Ioc容器中 只能有一个Bean满足条件 )

③ constructor其他bean的类型(class) 是否与 该Course类的构造方法参数 的类型一致;此种方式的本质就是byType



(3) 将ioc容器的所有bean 统一设置成自动装配

在 applicationContext.xml 头文件中添加:default-autowire="byName" 一次性将该ioc容器的所有bean 统一设置成自动装配

在这里插入图片描述


七、使用注解定义 bean

通过注解的形式 将bean以及相应的属性值 放入ioc容器

(1) 在appicationContext.xml 的头文件中添加:

xmlns:context="http://www.springframework.org/schema/context"

在这里插入图片描述
(2) 在appicationContext.xml 的中添加:

<context:component-scan base-package="org.lanqiao.entity"></context:component-scan>

在这里插入图片描述

Spring在启动的时候,会根据 base-package在 该包中扫描所有类,查找这些类是否有注解@Component("studentDao"),如果有,则将该类 加入spring Ioc容器。

@Component细化:
    ① dao层注解:@Repository
    ② service层注解:@Service
    ③ 控制器层注解:@Controller


八、使用注解实现事务(声明式事务)

通过事务 使方法 要么全成功、要么全失败

(1) 放入jar包:

① spring-tx-4.3.9.RELEASE
②mysql-connector-java-8.0.19.jar
③commons-dbcp.jar 连接池使用到数据源
④commons-pool.jar 连接池
⑤spring-jdbc-4.3.9.RELEASE.jar
⑥aopalliance.jar

(2) 配置

① 增加事务 tx 的命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
② 增加对事务的支持
<tx:annotation-driven transaction-manager="txManager"  />

从下往上补全:

<!-- 配置数据库相关 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="com.jdbc.cj.mysql.driver"></property>
	<property name="url" value="jdbc:mysql://127.0.0.1:3306/jdbc?serverTimezone=UTC"></property>
	<property name="username" value="root"></property>
	<property name="password" value="123456"></property>
	<property name="maxActive" value="10"></property>
	<property name="maxIdle" value="6"></property>
</bean>

<!-- 配置事务管理器txManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 增加对事务的支持 -->
<tx:annotation-driven transaction-manager="txManager" />

(3) 使用:

需要 成为事务的方法增加注解

@Transactional(readOnly=false,propagation=Propagation.REQUIRED)

九、基于XML 开发Spring AOP

通知实现步骤 :

(1) 添加 jar 包

① aopaliance.jar
② aspectjweaver.jar


(2) 编写 方法

① 通知类 XmlAdvice.java:
public class XmlAdvice {
	public void before(){
		System.out.println("这是前置通知...");
	}
	
	public void after(){
		System.out.println("这是后置通知...");
	}
}
② service 接口 IStudentService:
public interface IStudentService {
	public void addStudent();
	public void deleteStudent();
}
③ IStudentService 接口的实现类 StudentServiceImpl :
public class StudentServiceImpl implements IStudentService{
	@Override
	public void addStudent() {
		System.out.println("添加学生....");
		// int x = 5/0;  //异常:测试异常通知
	}

	@Override
	public void deleteStudent() {
		System.out.println("删除学生");
	}
}

(3) 配置 ApplicationContext.xml

① 先在 头文件 中加入 命名空间:
xmlns:aop="http://www.springframework.org/schema/aop"
② 注册bean 和 指定切点切面以及各种通知
<!-- 注册bean -->
<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl"></bean>
<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice"></bean>

<!-- 指定切点 -->
<aop:config>
	<aop:pointcut expression="execution(public void org.lanqiao.service.impl.StudentServiceImpl.*(..))" id="pointcut"/>
	<!-- 指定切面 -->
	<aop:aspect ref="xmlAdvice">
		<!-- 指定前置通知 -->
		<aop:before method="before" pointcut-ref="pointcut"/>
		<!-- 指定后置通知 -->
		<aop:after method="after" pointcut-ref="pointcut"/>
	</aop:aspect>
</aop:config>

(4) 测试 前置通知 和 后置通知

① 测试代码:
public static void testAOP() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	IStudentService studentService = (IStudentService)context.getBean("studentService");
	studentService.addStudent();
	studentService.deleteStudent();
}
② 运行结果:

在这里插入图片描述


(5) 测试:使用环绕通知实现前置,后置,异常通知

① 通知类 XmlAdvice.java 中加入around 方法
public Object around(ProceedingJoinPoint point)  {
		Object result = null;
		
		try{
			System.out.println("这是环绕通知实现的[前置通知]...");
			
			result = point.proceed();  //执行目标方法,addStudent()
			
			System.out.println("这是环绕通知实现的[后置通知]...");
			
		}catch(Throwablee){
			System.out.println("这是环绕通知实现的[异常通知]...");
			e.printStackTrace();
		}
		
		return result;
	}
② 注册bean 和 指定切点切面以及各种通知:
<!-- 注册bean -->
<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl"></bean>
<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice"></bean>

<aop:config>
	<!-- 指定切点 (StudentService中的所有方法) -->
	<aop:pointcut expression="execution(public void org.lanqiao.service.impl.StudentServiceImpl.*(..))" id="pointcut"/>
	<!-- 指定切面 -->
	<aop:aspect ref="xmlAdvice">
		<!-- 指定环绕通知 -->
		<aop:around method="around" pointcut-ref="pointcut"/>
	</aop:aspect>
</aop:config>

③ 测试代码:**

public static void testAOP() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	IStudentService studentService = (IStudentService)context.getBean("studentService");
	studentService.addStudent();
}

④ 运行结果:**
在这里插入图片描述


十、基于注解 开发Spring AOP

实现步骤:

(1) 添加 jar 包 (与 xml 方式 jar包相同)

① aopaliance.jar
② aspectjweaver.jar


(2) 编写 方法:

① IStudentService 接口的实现类

与 xml 不同之处: 使用注解注册bean

@Service("studentService") //等价于<bean id="studentService" 

StudentServiceImpl :

@Service("studentService") //等价于<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl">
public class StudentServiceImpl implements IStudentService{
	@Override
	public void addStudent() {
		System.out.println("添加学生....");
		int x = 5/0; //异常:测试异常通知
	}
}
② 通知类 XmlAdvice

与 xml 不同之处

//使用注解注册bean
@Component("xmlAdvice") 

//指定切面
@Aspect //通知

//指定环绕通知(指定切点)
@Around("execution(public * addStudent())")

XmlAdvice.java

@Component("xmlAdvice") //等价于<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice">
@Aspect //通知
public class XmlAdvice {
	@Around("execution(public * addStudent())")
	public Object around(ProceedingJoinPoint pj) {
		Object result = null;
		
		try{
			
			System.out.println("这是环绕通知实现的前置通知");
			
			result = pj.proceed();  //执行目标方法:addStudent()
			
			System.out.println("这是环绕通知实现的后置通知");
			
		}catch(Throwable e){
			System.out.println("这是环绕通知实现的异常通知");
			System.out.println("异常类型:" + e.getMessage().toString());
		}
		
		return result;
	}
}

(3) 配置 ApplicationContext.xml

① 先在 头文件 中加入 命名空间:
xmlns:aop="http://www.springframework.org/schema/aop"
② 设置扫描包 和 开启自动代理支持
<!-- 扫描包 -->
	<!-- 扫描 studentService,xmlAdvice 这两个bean --> 
	<context:component-scan base-package="org.lanqiao.aop , org.lanqiao.service"></context:component-scan>
	<!-- 开启 @aspectj 的自动代理支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(4) 测试 使用环绕通知实现前置,后置,异常通知

① 测试代码:
public static void testAOP() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	IStudentService studentService = (IStudentService)context.getBean("studentService");
	studentService.addStudent();
}
② 运行结果:

在这里插入图片描述


(5) 测试 多个切面的优先级

① 切面一 : Advice

order=1 值越小 优先级越高 (此时先执行后退出)

@Component("Advice")
@Aspect //指定切面
@Order(1) //值越小 优先级越高
public class Advice {
	
	@Before("execution(public * addStudent())") //指定切点
	public void before() {
		System.out.println("这是 切面Advice 的前置通知");
	}
	
	@After("execution(public * addStudent())") //指定切点
	public void after() {
		System.out.println("这是 切面Advice 的后置通知");
	}
}
② 切面二 : XmlAdvice:

@Order(3) 值越小 优先级越高 (此时后执行先退出)

@Component("xmlAdvice") //等价于<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice">
@Aspect //通知
@Order(3) //值越小 优先级越高
public class XmlAdvice {
	@Before("execution(public * addStudent())") //指定切点
	public void before() {
		System.out.println("这是 切面XmlAdvice 的前置通知....");
	}
	
	@After("execution(public * addStudent())")
	public void after() {
		System.out.println("这是 切面XmlAdvice 的后置通知....");
	}
}

③ 运行结果:

在这里插入图片描述


十一、使用 Spring 开发 Web 项目

1、Web项目如何初始化SpringIOC容器

思路:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供)

因此用spring开发web项目 至少需要7个jar

① spring-aop.jar (开发AOP特性时需要的 jar)
② spring-beans.jar (管理Bean的 jar)
③ spring-context.jar (处理spring上下文的 jar)
④ spring-core.jar (spring核心 jar)
⑤ spring-expression.jar (spring表达式 jar)
⑥ commons-logging.jar (三方提供,日志 jar)
⑦ spring-web.jar

[ 注意web项目的jar包 是存入到WEB-INF/lib中,否则后面可能会报错 ]

IOC容器初始化: web项目启动时 ,会自动加载web.xml,因此需要在web.xml加载 监听器


2、 web.xml 添加配置 :

(1) 指定IOC容器的位置
① web.xml :
<!-- 指定IOC容器 (applicationContext.xml) 的位置-->
<context-param>
 	 <!--  监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml -->
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:applicationContext.xml</param-value>
 </context-param>
   
<listener>
 	<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
 		初始化IOC容器 (applicationContext.xml)
			1:必须告诉监听器此容器的位置:context-param
			2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
 	 -->
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

② 运行结果:

在这里插入图片描述


(2) 不指定IOC容器的位置

将 applicationContext.xml 放在默认约定的位置:WEB-INF/applicationContext.xml
(xml文件名也不能改)
在这里插入图片描述

① web.xml :
<listener>
 	<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
 		初始化IOC容器 (applicationContext.xml)
 			1:必须告诉监听器此容器的位置:context-param
 			2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
 	 -->
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

②运行结果:

在这里插入图片描述


3、拆分 Spring 配置文件

(1) 按三层架构分:
① Dao:applicationContextDao.xml
② Service:applicationContextService.xml
③ Controller:applicationContextController.xml

(2) 加载多个配置文件:
① 方法一:param-value 中以逗号分隔:
<!-- 指定IOC容器 (applicationContext.xml) 的位置 -->
  <context-param>
  	   <!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml -->
    <param-name>contextConfigLocation</param-name>
    <param-value>
    	classpath:applicationContext.xml,
        classpath:applicationContextDao.xml,
    	classpath:applicationContextService.xml,
    	classpath:applicationContextController.xml
    </param-value>
  </context-param>
   
  <listener>
  	<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
  		初始化IOC容器 (applicationContext.xml)
  			1:必须告诉监听器此容器的位置:context-param
  			2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
  	 -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

运行结果:
在这里插入图片描述


② (推荐) 方法二:param-value 中用 * :
<!-- 指定IOC容器 (applicationContext.xml) 的位置 -->
  <context-param>
  	   <!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml -->
    <param-name>contextConfigLocation</param-name>
    <param-value>
    	classpath:applicationContext*.xml,
    </param-value>
  </context-param>
   
  <listener>
  	<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
  		初始化IOC容器 (applicationContext.xml)
  			1:必须告诉监听器此容器的位置:context-param
  			2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
  	 -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

运行结果:

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


③ (不推荐) 方法三:param-value 中只写主配置:

其他配置文件主配置文件 applicationContext.xml中 使用 <import resource=""/> 加入


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值