搭建Spring环境
下载jar
开发spring至少需要使用的jar(5个+1个)
spring提供的jar(5个)
- 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(1个)
- commons-logging-1.1.1.jar 日志
编写配置文件
为了编写时有一些提示,自动生成一些配置文件,如下方法:
- 给eclipse添加插件spring tool suite
- 使用STS开发 (此编辑器默认集成了 spring tool suite插件)
开发Spring程序(IOC)
IOC:控制反转 / DI:依赖注入
反转的是获取对象的方式:从new对象变成直接get对象
IOC的两种形式:
xml配置文件:applicationContext.xml
注解:带有@configuration注解的类(配置类)
存bean
@Configuraion public class MyConfig{ @Bean public Student myStudent(){ Student student = new Student(100,"zs"); student.setAddress(new Address("nz","ly")) return student; } }
取bean
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); Student student = (Student)context.getBean("myStudent");
作用:存bean 取bean
配置xml
文件名一般命名为:spring-context.xml、applicationContext.xml、beans.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.hui.entity.Student">
<!-- property:该class所代表的类的属性
name:属性名
value:属性值
-->
<property name="stuNo" value="1"></property>
<property name="stuName" value="zs"></property>
<property name="stuAge" value="18"></property>
</bean>
</beans>
DI依赖注入(三种方式):
通过set方法注入
如果是简单类型(8个基本+String)用value属性
如果是对象类型,ref=“需要引入的id值”
使用
<property name="属性名" value="值"></property>
通过构造方法注入
<constructor-arg value="html"></constructor-arg>
命名空间注入
中添加属性值
xmlns:p="http://www.springframework.org/schema/p"
<bean id="course" class="com.hui.entity.Course" p:courseHour="300" p:teacher-ref="teacher"></bean>
语法:p:属性名=“属性值”;p:属性名-ref=“id值”
注入各种集合类型:
array
<property name="list"> <list> <value>足球</value> <value>篮球</value> <value>乒乓球</value> </list> </property>
array
<property name="array"> <array> <value>足球1</value> <value>篮球1</value> <value>乒乓球1</value> </array> </property>
set
<property name="set"> <set> <value>足球2</value> <value>篮球2</value> <value>乒乓球2</value> </set> </property>
map
<property name="map"> <map> <entry> <key> <value>basketball</value> </key> <value>篮球3</value> </entry> <entry> <key> <value>pp3</value> </key> <value>乒乓球3</value> </entry> </map> </property>
properties
<props> <prop key="foot4">足球4</prop> <prop key="basket4">篮球4</prop> <prop key="pp4">乒乓球4</prop> </props>
测试类调用
public class Test {
public static void main(String[] args) {
//Spring上下文对象
ApplicationContext conext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student)conext.getBean("student");
System.out.println(stu);
}
}
springIOC已经帮我们new了对象并且赋了值
注解定义bean
在xml文件里添加:
<beans
xmlns:context="http://www.springframework.org/schema/context">
<context:component-scan base-package="com.hui.dao"></context:component-scan>
</beans>
具体的类:
@Component("studentDao")
public class StudetImpl {
@Autowired //自动装配
@Qualifier("stuDao") //根据名字装配(使用此注解必须要有上边的注解)
private IStudentDao studentDao;
public void addStudent(Student stu) {
System.out.println("添加学生...");
}
}
细化@Component:
功能一样,为了条例清晰使用相对应的注解
dao层注解:@Repository
service层注解:@Service
控制器层注解:@Controller
使用注解实现事务
jar包
- spring-tx-4.3.9.RELEASE.jar 事务包(官方包)
- ojdbc7.jar
- spring-jdbc-4.3.9.RELEASE.jar spring专用jdbc(官方包)
- aopalliance-1.0.jar
配置XML
<!-- 配置数据库相关 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></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"/>
具体方法
public class StudentServiceImpl implements IStudentService {
IStudentDao studentDao;
public void setStudentDao(IStudentDao studentDao) {
this.studentDao = studentDao;
}
//在需要成为事务的方法前添加此注解
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
@Override
public void addStudent(Student student) {
studentDao.addStudent(student);
}
}
AOP面向切面
面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
名词 | 简介 |
---|---|
切面(Aspect) | 一个横切功能的模块化,这个功能可能会横切很多个对象(业务)。例如,aMethod()方法就是一个“切面”,它横切到了多个业务之中。 |
切入点(Pointcut) | 可以插入"横切逻辑(如aMedthod())"的方法。例如,“调用add()”就是一个切点 |
通知(Advice):
通知类型 | 说明 | 对应接口 |
---|---|---|
前置通知(Before Advice) | 在切入点add()方法执行之前,插入的通知 | org.springframework.aop.MethodBeforeAdvice |
后置通知(After Returning) | 在切入点add()方法执行完毕之后,插入的通知 | org.springframework.aop.AfterReturningAdvice |
异常通知(After Throwing) | 当切入点add()方法抛出异常时,插入的通知。 | org.springframework.aop.ThrowsAdvice |
最终通知(After FinallyAdvice) | 当切入点add()方法执行完毕时,插入的通知(不论是正常返回还是一行退出) | |
环绕通知(Around Advice) | 可以贯穿切入点add()方法执行的整个过程。 | org.aopalliance.intercept.MethodInterceptor |
使用通知
切入点表达式练习
【修饰符 返回值 包.类 方法名 参数表】
<!-- 参数类型满足要求即可 -->
<aop:pointcut id="p1" expression="execution(* *(com.jun.entity.User))"/>
<!-- 匹配所有没有参数的方法 -->
<aop:pointcut id="p2" expression="execution(* *())"/>
<!-- 匹配saveUsesr方法 参数任意 -->
<aop:pointcut id="p3" expression="execution(* saveUser(..))"/>
<!-- 返回值为List的方法 -->
<aop:pointcut id="p4" expression="execution(java.util.List *(..))"/>
<!-- UserServiceImpl类中的所有方法 -->
<aop:pointcut id="p5" expression="execution(* com.jun.service.UserServiceImpl.*(..))"/>
<!-- service包下的所有方法 -->
<aop:pointcut id="p6" expression="execution(* com.jun.service.*.*(..))"/>
<!-- com..代表所有子包 下的所有类的所有方法 -->
<aop:pointcut id="p7" expression="execution(* com..*.*(..))"/>
-
jar包
-
配置
将业务类,通知纳入springIOC容器
定义切入点(一端),定义通知类(另一端),通过pointcut-ref将两端连接起来
<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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 配置前置通知 --> <!-- addStudent()所在的类 --> <bean id="studentServiceImpl" class="com.hui.service.StudentServiceImpl"> <property name="studentDao" ref="studentDao"></property> </bean> <!-- 前置通知所在的类 --> <bean id="logBefore" class="com.hui.aop.LogBefore"></bean> <!-- 将方法所在类和通知进行关联 --> <aop:config> <!-- 配置切入点(在那里执行通知) --> <aop:pointcut expression="execution(public void com.hui.service.StudentServiceImpl.deleteStudentByNo(int)) or execution(public void com.hui.service.StudentServiceImpl.addStudent(com.hui.entity.Student))" id="pointcut"/> <!-- advisor:相当于连接切入点和切面的线 --> <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/> </aop:config> </beans>
-
编写
↓↓↓↓↓↓↓↓↓
异常置通知
根据异常通知接口的定义,异常通知的实现类 必须编写一下方法
public void afterThrowing([Method, args, target], ThrowableSubclass);
//例如:
//异常通知的具体方法
public void afterThrowing(Method method,Object[] args,Object target,Throwable ex ) {
System.out.println("异常通知,目标对象:"+target+",方法:"+method.getName()+",参数个数:"+args.length+",异常类型:"+ex);
}
环绕通知
在目标方法的前、后、异常、最终等各个地方都可以进行的通知,最强大的通知 可以获取目标的方法的全部 控制权(目标方法是否执行、执行之前、执行之后、参数、返回值等)
目标方法的一切信息都可以通过invocation参数获取到
public class LogAround implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = null;
//方法体1
try {
//方法体2
System.out.println("用环绕通知实现的前置通知...");
//invocation.proceed()之前的代码就是前置通知
//result就是目标方法的返回值
result = invocation.proceed();//控制着目标方法的执行
//invocation.proceed()之后的代码就是后置通知
System.out.println("用环绕通知实现的后置通知...");
System.out.println("目标对象:"+invocation.getThis()+",方法:"+invocation.getMethod().getName()+",参数个数:"+invocation.getArguments().length+",方法返回值:"+result);
} catch (Exception e) {
//此部分就是异常通知
System.out.println("用环绕通知实现的异常通知");
}
return result;
}
}
注解实现通知
-
jar
与实现接口的方式相同
-
配置
将业务类、通知 纳入springIOC中
开启注解对AOP的支持
<!-- 开启注解对AOP的支持 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 配置扫描器——扫描注解 --> <context:component-scan base-package="com.hui.aop"></context:component-scan> <!-- 扫描器会将指定的包中的 @Component @Service @Respository @Controller修饰的类产生的对对象增加到IOC容器中 -->
-
编写
import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component("logAnnotation") //加入IOC容器 属性:id值 @Aspect //声明该类是一个通知 public class LogBeforeAnnotation { //前置通知 @Before("execution(public void addStudent(com.hui.entity.Student))")//属性:定义切点 public void myBefore(JoinPoint jp) { System.out.println("[注解形式-前置通知]:目标对象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName()+",参数列表:"+Arrays.toString(jp.getArgs())); } //后置通知 @AfterReturning(pointcut = "execution(public boolean addStudent(int))",returning = "returningValue") public void myAfter(JoinPoint jp,Object returningValue) { System.out.println("[注解形式-后置通知],返回值:"+returningValue); } //环绕通知 @Around("execution(public void addStudent(com.hui.entity.Student))") public void myAround(ProceedingJoinPoint jp) { //方法执行之前 System.out.println("[环绕:前置通知]"); try { //方法执行时 jp.proceed();//执行方法 //方法执行之后 System.out.println("[环绕:后置通知]"); } catch (Throwable e) { //发生异常时 System.out.println("[环绕:异常通知]"); }finally { //最终通知 System.out.println("[环绕:最终通知]"); } } //异常通知 如果只捕获特性类型异常,则可以通过第二个参数实现 @AfterThrowing(pointcut = "execution(public void addStudent(com.hui.entity.Student))",throwing="e") public void myException(JoinPoint jp,NullPointerException e) { System.out.println("[注解形式-异常通知]e:"+e.getMessage()); } //最终通知 @After("execution(public void addStudent(com.hui.entity.Student))") public void myAfter() { System.out.println("[注解形式-最终通知]"); } }
Spring开发web程序
Web项目如何初始化SpringIOC容器?
思路:
当服务器启动时,通过监听器将SpringIOC容器初始化一次
↓↓↓↓↓
监听器:监听tomcat是否启动,一旦启动就实例化一个IOC容器,此监听器不需要自己写
sping-web.jar
中已包含
web.xml中的配置
将Spring引入web项目中
<!-- 方式1:指定IOC容器的位置,告诉监听器IOC容器的位置
方式2:可以不指定位置,路径为:WebContent/WEB-INF/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)必须告诉监听器此容器的位置 -->
<listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
</listener>
Spring整合MyBatis
思路:
MyBatis操作数据库流程:SqlSessionFactory->SqlSession->StudenntMapper->CRUD
可以发现,MyBatis最终是通过SqlSessionFactory来操作数据库,Spring整合MyBatis其实就是将SqlSessionFactory教给Spring管理
整合步骤
-
jar
mybatis-spring.jar spring-tx.jar spring-jdbc.jar spring-expression.jar spring-context-support.jar spring-core.jar spring-contexxt.jar spring-beans.jar spring-aop.jar spring-web.jar log4.jar mybatis.jar commons-logging.jar commons-pool.jar commons-dbcp.jar
-
类–表
-
MyBatis配置文件conf.xml
-
通过mapper.xml将 类、表建立映射关系
可省,将该文件中的配置 全部交给spring管理
-
通过sprnig配置文件产生SqlSessionFactory
产生sqlSessionFactory所需的数据库信息不放入conf.xml 而需要放入spring(applicationContext.xml)配置文件中
<beans> <!-- 加载db.properties --> <bean id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"> <property name="locations"> <array> <value>classpath:db.properties</value> </array> </property> </bean> <!-- 配置数据库信息(替代mybatis的配置文件conf.xml) --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${driver}"></property> <property name="url" value="${url}"></property> <property name="username" value="${username}"></property> <property name="password" value="${password}"></property> <property name="maxActive" value="${maxActive}"></property> <property name="maxIdle" value="${maxIdle}"></property> </bean> <!-- 在SpringIOC容器中创建MyBatis的核心类SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 加载mybatis配置文件 --> <property name="mapperLocations" value="com/hui/mapper/*.xml"></property> </property> </bean> </beans>
-
使用Spring-MyBatis整和产物开发程序
目标:通过spring产生mybatis最终操作需要的动态mapper对象(StudentMapper对象)
三种方法:
-
第一种方式
DAO层实现类继承SqlSessionDaoSupport类,该类提供了一个属性SqlSession(用于产生mapper对象)
public class StudentDaoImpl extends SqlSessionDaoSupport implements StudentMapper { @Override public void addStudent(Student student) { SqlSession session = super.getSqlSession(); StudentMapper stuDao = session.getMapper(StudentMapper.class); stuDao.addStudent(student); } }
<bean id="studentMapper" class="com.hui.dao.impl.StudentDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
-
第二种方式
省略掉第一种方式的实现类,直接使用MyBatis提供的Mapper实现类:MapperFactoryBean
缺点:每个mapper都需要一个实现类
<bean id="studentMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.hui.mapper.StudentMapper"></property> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
-
第三种方式
批量配置实现类
<!-- 第三种生成mapper方式 (批量产生多个mapper) 批量产生Mapper对像时SpringIoc中的id值默认就是接口名(首字母小写)--> <bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> <!-- 指定批量产生哪个包下的mapper对象 --> <property name="basePackage" value="com.hui.mapper"></property> </bean> <bean id="studentServiceImpl" class="com.hui.service.impl.StudentServiceImpl"> <property name="studentMapper" ref="studentMapper"></property> </bean>
-
SSM整合
Spring - SprigMVC - MyBatis
Spring - MyBatis
结合上方的sm整合操作
Spring - SpringMVC
将speingMVC加入项目即可
先引入jia包:spring-webmvc-4.3.9.RELEASE.jar
1.配置springmvc
web.xml
<!-- 项目整合springMVC -->
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-controller.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.编写springmvc配置文件
<!-- 配置视图解析器 -->
<bean id="" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- Springmvc基础配置 -->xml
<mvc:annotation-driven></mvc:annotation-driven>
看到最后希望大家能有所收获,感谢观看,加油打工人!!!