ssm–spring
1.Spring概念
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
2.Spring配置
2.1别名
<!--别名,如果添加了别名,我们也可以通过别名获取到这个对象,name是原bean的id, alias是别名-->
<alias name="user" alias="userNew"/>
2.2 bean标签
<!--
id: bean 的唯一标识符,也就是相当于对象名
class:bean对象所对应的全限定类名,包名+类名
name:也是别名,而且name可以一同时取多个别名,多个别名可以用空格/逗号/分号分隔
-->
<bean id="user" class="com.test.user" name="user1 user2,user3;user4">
<property name="name" value="123"/>
</bean>
2.3 import
<!--主要用于团队开发,可以导入别人的配置-->
<import resource="bean1.xml"/>
3.SpringIOC
有了IOC以前,对象是程序员主动创建的,控制权在程序员手上,用户要更改需求必须让程序员修改service业务层,当有了IOC,使用set注入后,程序员不具有主动性,而是变成了被动的接受对象,用户只需要为set方法提供参数就可以了,主动权变成了用户。
(1)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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BeanTest" class="com.ouc.bean.BeanTest">
<!-- collaborators and configuration for this bean go here -->
<!-- 方式一:set方法/无参构造器注入,默认,bean实体类中必须有set方法,无参构造器类中没用构造器时默认提供,但是如果类中有其他构造器,则必须也定义无参构造器-->
<property name="id" value="12"></property>
<!-- 方式二:有参构造器注入,bean实体类中必须有有参构造器-->
<!--2.1下标赋值-->
<!--<constructor-arg index="0" value="10"></constructor-arg>-->
<!--<constructor-arg index="1" value="jack"></constructor-arg>-->
<!--2.2类型赋值-->
<!--<constructor-arg type="int" value="10"></constructor-arg>-->
<!--<constructor-arg type="java.lang.String" value="jack"></constructor-arg>-->
<!--2.3参数名赋值-->
<!--<constructor-arg name="id" value="10"></constructor-arg>-->
<!--<constructor-arg name="name" value="jack"></constructor-arg>-->
</bean>
<!-- more bean definitions go here -->
</beans>
复杂类型的xml注入
package com.ouc.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class BeanTest {
private String[] strs;
private List list;
private Set set;
private Map map;
private Properties properties;
public BeanTest() {
}
public String[] getStrs() {
return strs;
}
public void setStrs(String[] strs) {
this.strs = strs;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BeanTest" class="com.ouc.bean.BeanTest">
<!-- collaborators and configuration for this bean go here -->
<!--数组-->
<property name="strs">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<!--list集合-->
<property name="list">
<list>
<value>111</value>
<value>222</value>
<value>333</value>
</list>
</property>
<!--set集合-->
<property name="set">
<set>
<value>eee</value>
<value>fff</value>
<value>ddd</value>
</set>
</property>
<!--map集合-->
<property name="map">
<map>
<entry key="one" value="ggg"></entry>
<!--<entry key="two">hhh</entry>-->
</map>
</property>
<!--properties-->
<property name="properties">
<props>
<prop key="one">ttt</prop>
</props>
</property>
</bean>
<!-- more bean definitions go here -->
</beans>
ps:数组/list/set list标签/set标签/array标签通用;
map和properties map标签/props标签通用;
结论:结构相同,标签可以互换。
(2)注解注入
使用注解前提
spring4之后,注解开发必须先导入spring-aop相关jar包
- 导入约束
- 开启注解支持
<?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">
<!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.dao"/>
<!--开启注解支持-->
<context:annotation-config/>
</beans>
@Autowired: 自动装配,直接放在属性上即可,用了这个之后,set方法也可以省略了
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注释【@Autowired】来完成,我们可以使用@Qualifier(value=“xxx”)去配和@Autowired使用。
@Component: 等价于,这个注解放在类上说明这个类被spring管理了,就是bean。
@Component衍生注解:@Repository;@Service;@Controller 这仨功能一样
@Value:等价于,这个注解放在属性上,相当于给属性赋值。
@Scope:作用域@Scope(“singleton”)单例;@Scope(“prototype”)多例
(3)测试
public static void main(String[] args) {
//获取ApplicationContext,拿到spring容器
ApplicationContext context=new ClassPathXmlApplicationContext("配置文件名.xml");
TestServer testServer = (TestServer) context.getBean("TestServer");
}
3.springAOP
3.1 原生aop方式
(1)创建log类实现下列四种接口其中之一
public class Log implements MethodBeforeAdvice{
public void before(Method method,Object[] args,Object target){
System.out.println("target.getClass().getName()+\"的\"+method.getName()+\"被执行了\" = " + target.getClass().getName() + "的" + method.getName() + "被执行了");
}
}
(2)配置文件配置aop
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="beantest" class="com.ouc.bean.BeanTest">
<property name="id" value="10"></property>
<property name="name" value="122"></property>
</bean>
<bean id="logbefore" class="com.ouc.service.Log"></bean>
<aop:config>
<aop:pointcut id="pointcut1" expression="execution(* com.ouc.bean.BeanTest.getId())"/>
<aop:advisor advice-ref="logbefore" pointcut-ref="pointcut1"></aop:advisor>
</aop:config>
</beans>
3.2 简化方式配置aop
(1)写log类
public class Log{
public void before(){
System.out.println("执行了before");
}
public void afterReturn(){
System.out.println("执行了afterReturn");
}
}
(2)配置文件中配置aop
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="beantest" class="com.ouc.bean.BeanTest">
<property name="id" value="10"></property>
<property name="name" value="122"></property>
</bean>
<bean id="log" class="com.ouc.service.Log"></bean>
<aop:config>
<aop:pointcut id="pointcut1" expression="execution(* com.ouc.bean.BeanTest.getId())"/>
<aop:aspect ref="log">
<aop:before method="before" pointcut-ref="pointcut1"></aop:before>
<aop:after-returning method="afterReturn" pointcut-ref="pointcut1"></aop:after-returning>
</aop:aspect>
</aop:config>
</beans>
3.3 注解配置aop
(1)开启注解aop
<?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
https://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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解配置-->
<context:component-scan base-package="com.ouc.bean"></context:component-scan>
<!--开启注解aop-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
(2)定义一个切面类(这个类所在的包,在beans.xml中也要加进扫描里)
package com.ouc.bean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component("log")
@Aspect
public class Log {
@Pointcut("execution(* com.ouc.bean.BeanTest.*())")
private void pointcut(){
}
@Before("pointcut()")
public void before() {
System.out.println("执行了前置通知");
}
@AfterReturning("pointcut()")
public void afterReturn() {
System.out.println("执行了后置通知");
}
@After("pointcut()")
public void after(){
System.out.println("执行了最终通知");
}
@AfterThrowing("pointcut()")
public void afterThrowing(){
System.out.println("执行了异常通知");
}
//环绕通知必须有返回值,返回proceed产生的对象,否则报错:org.springframework.aop.AopInvocationException: Null return value from XXXXXXX
@Around("pointcut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕后");
return proceed;
}
}
ps://环绕通知必须有返回值,返回proceed产生的对象,否则报错:org.springframework.aop.AopInvocationException: Null return value from XXXXXXX
4.Spring事务
(1)加入事务相关约束
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
(2)开启注解配置
<context:component-scan base-package="com.ouc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
(3)完善数据库连接池和mybatis相关配置
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--批量执行的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<!--SIMPLE 支持返回的操作个数;BATCH返回一个大的负数 -->
<constructor-arg name="executorType" value="SIMPLE"></constructor-arg>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ouc.dao"></property>
</bean>
(4)配置事务管理器
<bean id="transanctionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transanctionManager">
<tx:attributes>
<tx:method name="selectStudentAll" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
(5)将事务放入aop切面
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.ouc.service.AdminStudentService.*())"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
最终版本:
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--开启注解配置-->
<context:component-scan base-package="com.ouc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="transanctionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transanctionManager">
<tx:attributes>
<tx:method name="selectStudentAll" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.ouc.service.AdminStudentService.*())"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--批量执行的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<!--SIMPLE 支持返回的操作个数;BATCH返回一个大的负数 -->
<constructor-arg name="executorType" value="SIMPLE"></constructor-arg>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ouc.dao"></property>
</bean>
</beans>
Spring使用步骤(aop和事务均使用xml配置)
1.导入约束,基本约束/context约束/aop约束/tx约束
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
2.开启注解配置
<!--开启注解配置-->
<context:component-scan base-package="com.ouc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
3.配置数据库连接池
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--批量执行的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<!--SIMPLE 支持返回的操作个数;BATCH返回一个大的负数 -->
<constructor-arg name="executorType" value="SIMPLE"></constructor-arg>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
4.整合mybatis
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ouc.dao"></property>
</bean>
5.配置事务管理器
<bean id="transanctionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
6.配置事务通知
<tx:advice id="txAdvice" transaction-manager="transanctionManager">
<tx:attributes>
<tx:method name="selectStudentAll" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
7.定义一个通知类
@Component("log")
public class Log {
public void before() {
System.out.println("执行了前置通知");
}
public void afterReturn() {
System.out.println("执行了后置通知");
}
public void after(){
System.out.println("执行了最终通知");
}
public void afterThrowing(){
System.out.println("执行了异常通知");
}
//环绕通知必须有返回值,返回proceed产生的对象,否则报错:org.springframework.aop.AopInvocationException: Null return value from XXXXXXX
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕后");
return proceed;
}
}
8.配置aop
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.ouc.service.AdminStudentService.*())"/>
<!--事务通知-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
<!--log通知-->
<aop:aspect ref="log">
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<aop:after-returning method="afterReturn" pointcut-ref="pointcut"></aop:after-returning>
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"></aop:after-throwing>
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
</aop:aspect>
</aop:config>