1.IOC:控制反转(DI:依赖注入)对控制反转和依赖注入的理解:
其中原理是利用反射机制调用setXxx方法
2.新建的applicationContext.xml虽然是xml文件,但是是一个bean类型,新建时应按下图选择。
3.applicationContext.xml中新增加对象的方式(简单对象用value,如果是对象类型,用ref,且值为需要应用的id值):
4.获得对象的三种方法:
- 直接new,最麻烦,代码分散,不好管理
- 用工厂管理,代码相对流畅,易于管理
- 用ioc容器,是一个超级工厂
5.三种赋值方式:
-
根据属性的setXxx方法赋值:
注意:在ioc中定义bean的前提,该bean的类必须提供了无参构造
-
根据构造方法赋值(顺序分别对应构造方法中的属性顺序):
-
p命名空间赋值
-
当属性是对象类型时,需要在属性名后加-ref
注意:value与<value>注入的区别
6.对集合类型的属性赋值
注入各种集合数据类型: List Set map properties
7.给对象类型赋null值与“”的区别
给对象类型赋值null :
<property name="name" >
<null/> #注意 没有<value>
</property>
赋空值 ""
<property name="name" >
<value></value>
</property>
8.自动装配
(只适用于 ref类型 ):
约定优于配置
自动装配:
<bean ... class="org.lanqiao.entity.Course" autowire="byName|byType|constructor|no" >
byName本质是byId
byName: 自动寻找:其他bean的id值=该Course类的属性名
byType: 其他bean的类型(class) 是否与 该Course类的ref属性类型一致 (注意,此种方式 必须满足:当前Ioc容器中 只能有一个Bean满足条件 )
constructor: 其他bean的类型(class) 是否与 该Course类的构造方法参数 的类型一致;此种方式的本质就是byType
可以在头文件中 一次性将该ioc容器的所有bean 统一设置成自动装配:
<beans xmlns="http://www.springframework.org/schema/beans"
...
default-autowire="byName">
自动装配虽然可以减少代码量,但是会降低程序的可读性,使用时需要谨慎。
9.使用注解定义bean
通过注解的形式 将bean以及相应的属性值 放入ioc容器
<context:component-scan base-package="org.lanqiao.dao">
</context:component-scan>
Spring在启动的时候,会根据base-package在 该包中扫描所有类,查找这些类是否有注解@Component("studentDao"),如果有,则将该类 加入spring Ioc容器。
@Component细化:
dao层注解:@Repository
service层注解:@Service
控制器层注解:@Controller
10.使用注解实现声明性事务
待学习
11.AOP:面向方面编程
一个普通的类 -> 有特定功能的类
a.继承类 b.实现接口 c.注解 d.配置
public class MyFilter exntends/implements Xx
{
}
类 -> “通知” :实现接口
前置通知实现步骤:
a.jar
aopaliance.jar
aspectjweaver.jar
c.编写
aop:每当之前add()之前 自动执行一个方法log();
addStudent(); 业务方法(IStudentService.java中的 addStudent())
before(); 自动执行的通知,即aop前置通知
public class Xxx
{
@Test
a(){}
}
如果出现异常:类似java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
则说明缺少jar
后置通知:
a.通知类 ,普通实现接口
b.业务类、业务方法
StudentServiceImpl中的addStudent()
c.配置:
将业务类、通知 纳入springIOC容器
定义切入点(一端)、定义通知类(另一端),通过pointcut-ref将两端连接起来
异常通知:
根据异常通知接口的定义可以发现,异常通知的实现类 必须编写以下方法:
public void afterThrowing([Method, args, target], ThrowableSubclass):
a.public void afterThrowing(Method, args, target, ThrowableSubclass)
b.public void afterThrowing( ThrowableSubclass)
环绕通知: 在目标方法的前后、异常发生时、最终等各个地方都可以 进行的通知,最强大的一个通知;
可以获取目标方法的 全部控制权(目标方法是否执行、执行之前、执行之后、参数、返回值等)
在使用环绕通知时,目标方法的一切信息 都可以通过invocation参数获取到
环绕通知 底层是通过拦截器实现的。
12.基于注解形式的AOP
a.jar
与实现接口的方式相同
b.配置
将业务类、通知纳入springIOC容器
开启注解对AOP的支持<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
业务类addStudent - 通知
c.编写
通知:
@Aspect //声明该类是一个通知
注意:通过注解形式 将对象增加到 ioc容器时,需要设置 扫描器
<context:component-scan base-package="org.lanqiao.aop"></context:component-scan>
扫描器 会将 指定的包 中的 @Componet @Service @Respository @Controller修饰的类产生的对象 增加到IOC容器中
@Aspect不需要 加入扫描器,只需要开启即可:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
通过注解形式 实现的aop,如果想获取 目标对象的一些参数,则需要使用一个对象:JointPoint
注解形式的返回值:
a.声明返回值 的参数名:
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" )
public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告诉spring
System.out.println("返回值:"+returningValue );
注解形式实现aop时,通知的方法的参数不能多、少
实现接口形式、注解形式 只捕获声明的特定类型的异常,而其他类型异常不捕获。
13.基于Schema配置实现AOP
类似 与 实现接口的方式
- 接口方式通知:public class LogAfter implements AfterReturningAdvice
- Schema方式通知:
a.编写一个普通类 public class LogAfter {}
b.将该类 通过配置,转为一个“通知”
如果要获取目标对象信息:
注解、schema:JoinPoint
接口:Method method, Object[] args, Object target
schema形式 和注解形式相似,不同之处: 注解形式 使用了注册@After, schmema形式进行了多余的配置
14.spring开发Web项目
Web项目如何初始化SpringIOC容器 :思路:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供)
因此用spring开发web项目 至少需要7个jar: spring-java的6个jar + spring-web.jar,
注意:web项目的jar包 是存入到WEB-INF/lib中
web项目启动时 ,会自动加载web.xml,因此需要在web.xml中加载 监听器(ioc容器初始化)。
Web项目启动时,启动实例化Ioc容器:
<!-- 指定 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
-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
15.拆分spring配置文件
- java项目:
applicationContext1.xml
applicationContext2.xml
applicationContext3.xml
ApplicationContext conext = new ClassPathXmlApplicationContext("applicationContext3.xml") ;
- Web项目:
根据什么拆分?
i.三层结构
UI(html/css/jsp 、Servlet) applicationController.xml
Service :applicationService.xml
Dao:applicationDao.xml
公共 数据库:applicationDB.xml
ii.功能结构
学生相关配置 applicationContextStudent.xml <bean id="" class="X...Student">
班级相关配置 applicationContextClass.xml
合并:如何将多个配置文件 加载
(1)
<context-param>
<!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值 保存着 容器配置文件applicationContext.xml的位置 -->
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-Dao.xml,
classpath:applicationContext-Service.xml,
classpath:applicationContext-Controller.xml
</param-value>
</context-param>
(2)推荐
<context-param>
<!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值 保存着 容器配置文件applicationContext.xml的位置 -->
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-*.xml
</param-value>
</context-param>
(3)只在web.xml中加载主配置文件,
<param-value>
classpath:applicationContext.xml
</param-value>
然后在主配置问加中,加载其他配置文件
<import resource="applicationContext-*.xml"/>
16.Spring整合mybatis
思路:
SqlSessionFactory -> SqlSession ->StudentMapper ->CRUD
可以发现 ,MyBatis最终是通过SqlSessionFactory来操作数据库,
Spring整合MyBatis 其实就是 将MyBatis的SqlSessionFactory 交给Spring
SM整合步骤:
1.jar
mybatis-spring.jar spring-tx.jar spring-jdbc.jar spring-expression.jar
spring-context-support.jar spring-core.jar spring-context.jar
spring-beans.jar spring-aop.jar spring-web.jar commons-logging.jar
commons-dbcp.jar ojdbc.jar mybatis.jar log4j.jar commons-pool.jar
2.类-表
3.MyBatis配置文件conf.xml
4.通过mapper.xml将 类、表建立映射关系
之前使用MyBatis: conf.xml ->SqlSessionFacotry
现在整合的时候,需要通过Spring管理SqlSessionFacotry ,因此 产生qlSessionFacotry 所需要的数据库信息 不在放入conf.xml 而需要放入spring配置文件中
配置Spring配置文件(applicationContext.xml)
6.使用Spring-MyBatis整合产物开发程序
目标:通过spring产生mybatis最终操作需要的 动态mapper对象(StudentMapper对象)
Spring产生 动态mapper对象 有3种方法:
a.第一种方式
DAO层实现类 继承 SqlSessionDaoSupport类
SqlSessionDaoSupport类提供了一个属性 SqlSession
b.第二种方式
就是省略掉 第一种方式的 实现类
直接MyBatis提供的 Mapper实现类:org.mybatis.spring.mapper.MapperFactoryBean
缺点:每个mapper都需要一个配置一次
c.第三种方式
批量配置 实现类
注意:
Autowired+Service+Repository是通过byType自动装配的
Autowired、Qualifier(name)+Service(name)+Reposutory(name)是通过byName自动装配的