Spring(有不清楚的直接去笔记看)
1 环境搭建
至少得导入这几个包,在src下创建application.xml配置文件,把需要用到的功能的schema约束从文档中写入配置文件中
2 如何创建对象?
创建对象的三个方法
1 构造方法
无参
<bean id="People" class="com.liuyi.pojo.People">
</bean>
创建了bean如何获得?
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
People p=ac.getBean("People",People.Class);
有参构造方法 index表示从第几个参数开始,name是参数名
2 工厂创建对象
要先创建一个工厂类,工厂类内有提供自己想要实现的类的方法
public class PeopleFactory {
public People newInstance(){
return new People(1,"测试");}
}
工厂类也要在xml文件里配置bean,factory-method是工厂类生成对象的方法
<bean id="factory" class="com.bjsxt.pojo.PeopleFactory"></bean>
<bean id="peo1" factory-bean="factory" factory-method="newInstance">
</bean>
3 静态工厂,比工厂少一步,不用在xml内再创建工厂的bean
public class PeopleFactory {
public static People newInstance(){
return new People(1,"测试");}
}
<bean id="peo1" factory-bean="factory" factory-method="newInstance">
</bean>
3 给Bean的属性赋值(注入)
如果bean的属性是基本数据类型或String
<bean id="peo" class="com.liuyi.pojo.People">
<property name="id" value="1"></property>
<property name="name" value="张家辉"></property>
</bean>
set<?>类型
<property name="sets">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</set>
</property>
如果属性是 List<?>
<property name="list">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
如果属性是数组
<property name="strs" >
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
如果属性是 map
<property name="map">
<map>
<entry key="a" value="b" >
</entry>
<entry key="c" value="d" >
</entry>
</map>
</property>
如果属性 Properties 类型
<property name="demo">
<props>
<prop key="key">value</prop>
<prop key="key1">value1</prop>
</props>
</property>
4 DI(依赖注入)当A类需要B类,把B赋值给A就叫依赖注入
5 使用Spring简化Mybatis.xml(整合Spring和Mybatis)
导入所有mybatis和spring需要的包,还有mybatis整合spring的包
首先配置web.xml,WEB-INF下的,监听器在web包下,复制全路径
接下来而在application.xml配置所有Mybatis需要的东西,Mybatis配置文件可以不写了
加载数据库,类在spring-jdbc包
加载session工厂,类在mybatis整合spring.jar
扫描mapper包的 com.liuyi.mapper包,扫描器相当于 mybatis.xml 中 mappers 下 package 标
签,扫描 com.bjsxt.mapper 包后会给对应接口创建对象,里面两个属性值名是固定的,basePackage和sqlSessionFactory
spring与mybatis整合并且有用Tomcat的话,通过这样的方式管理service,service下有个userMpper的接口,并且要有mapper的get set方法,因为 <property>标签是通过set/get方法来赋值的
在servlet使用service时在init方法通过getBean方法取出
ApplicationContext ac =WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
ac.getBean("userService",userServiceImp.Class);
6 AOP 面向切面编程,用aop要用cglib动态代理,
1.AOP:中文名称面向切面编程
2.英文名称:(Aspect Oriented Programming)
3.正常程序执行流程都是纵向执行流程
3.1 又叫面向切面编程,在原有纵向执行流程中添加横切面
3.2 不需要修改原有程序代码
3.2.1 高扩展性
3.2.2 原有功能相当于释放了部分逻辑.让职责更加明确
4.面向切面编程是什么?
4.1 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面过程就叫做面向切面编程.
5.常用概念
5.1 原有功能: 切点, pointcut
5.2 前置通知: 在切点之前执行的功能. before advice
5.3 后置通知: 在切点之后执行的功能,after advice
5.4 如果切点执行过程中出现异常,会触发异常通知.throws advice
5.5 所有功能总称叫做切面.
5.6 织入: 把切面嵌入到原有功能的过程叫做织入
6.spring 提供了 2 种 AOP 实现方式
6.1 Schema-based
6.1.1 每个通知都需要实现接口或类
6.1.2 配置 spring 配置文件时在<aop:config>配置
6.2 AspectJ
6.2.1 每个通知不需要实现接口或类
6.2.2 配置 spring 配置文件是在<aop:config>的子标签<aop:aspect>中配置
如何实现?这里只介绍schema方式
导入相关jar包,不知道可以百度查
简单来说就是定义一个类,根据自己需要的是前置,后置,还是,环绕通知,实现相关前置,后置,或者环绕通知接口
前置 MethodBeforeAdvice
arg0: 切点方法对象 Method 对象
arg1: 切点方法参数
arg2:切点在哪个对象中
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method arg0, Object[] arg1, Objectarg2) throws Throwable {
System.out.println("执行前置通知");
}
}
后置 AfterReturningAdvice
arg0: 切点方法返回值
arg1:切点方法对象
arg2:切点方法参数
arg3:切点方法所在类的对象
public class MyAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object arg0, Method arg1,Object[] arg2, Object arg3) throws Throwable {
System.out.println("执行后置通知");
}
}
配置文件的写法
需要设置一个切点,通常是一个方法,在这个切点前叫前置通知,切点后叫后置通知,环绕通知就是前后都有
<bean id="mybefore"class="com.bjsxt.advice.MyBeforeAdvice"></bean>
<bean id="myafter"class="com.bjsxt.advice.MyAfterAdvice"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(*com.bjsxt.test.Demo.demo2())" id="mypoint"/>
<!-- 通知 -->
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/>
</aop:config>
<!-- 配置 Demo 类,测试使用 -->
<bean id="demo" class="com.bjsxt.test.Demo">
</bean>
</beans>
环绕通知 MethodInterceptor
public class MyArround implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0)throws Throwable {
System.out.println("环绕-前置");
Object result = arg0.proceed();//放行,调用切点方式System.out.println("环绕-后置");
return result;
}
}
配置文件
<bean id="myarround" class="com.bjsxt.advice.MyArround"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="myarround" pointcut-ref="mypoint" />
</aop:config>
<bean id="demo" class="com.bjsxt.test.Demo"></bean>
异常通知(Schema-based 方式
1. 新建一个类实现 throwsAdvice 接口
1.1 必须自己写方法,且必须叫 afterThrowing
1.2 有两种参数方式
1.2.1 必须是 1 个或 4 个
1.3 异常类型要与切点报的异常类型一致
public class MyThrow implements ThrowsAdvice{
public void afterThrowing(Exception ex) throws Throwable {
System.out.println("执行异常通过-schema-base 方式");
}
}
2. 在 ApplicationContext.xml 配置
<bean id="mythrow" class="com.bjsxt.advice.MyThrow"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="mythrow"pointcut-ref="mypoint" />
</aop:config>
<bean id="demo" class="com.bjsxt.test.Demo"></bean>
7 声明式事务 (需要和aop一起使用,因为是基于aop)
在配置文件这样配置
在 <tx:method> 可以配置以下这样的值
propagation 控制事务传播行为.
3.1 当一个具有事务控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异
常?)
3.2 REQUIRED (默认值): 如果当前有事务,就在事务中执行,如果当前没有事务,新建一个事务.
3.3 SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行.
3.4 MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错.
3.5 REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起.
3.6 NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起.
3.7 NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错.
3.8 NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务.