一、Spring 特点
- IOC(inverse of control) 控制反转,java去操作文件,spring文件来操作代码(用反射)
- DI(dependency inject) 依赖注入
- AOP(aspect orient programming) 面向切面编程
struts 是MVC框架,Hibernate是ORM框架(object relation mapping)对象关系映射
二、开发步骤
- 创建普通java工程
- 添加Spring支持 <bean id="sum" class="com.etc.Main">
- 写Main类,在applicationContext.xml中配置一下bean
- 用junit来测试,加载spring的配置文件,调用get bean 方法
//写测试类
public class MainTest{
@Test
public void testSum(){
//1加载spring配置
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.得到bean spring提供了容器的功能
Main main =(Main)context.getBean("sum");
int s = main.sum(1,2);
System.out.println(s);
}
}
三、配置
<property name="" value=""><property>
1 Getter/Setter 配置:通过<bean>中的<property>配置user类的属性——(控制反转)
2 构造器配置
3 Ref 引用配置(依赖注入)
4 集合的配置
5 懒加载 延迟加载 项目里配置很多<bean>后 启动服务器会很慢 ,所以可以使用懒加载
在<bean laze-init="default"> (局部)默认default,不懒加载,要手动设为true。
<!-- default-lazy-init="true" --> (全局)
6 自动装配<bean autowire=""> by name 和 by type
7 作用范围 <bean scope="singleton"> 默认为singletons//单例,内存中只有一份
prototype//原型 ,每次都是新的。在ssh整合中,struts的action 要设置为prototype。
8 生命周期 <bean init-method="init" destroy-method="destroy"> bean 被创建的时候会自动创建 这两个方法。
四、AOP
1什么是AOP?
面向切面编程,将一个方法的开始部分和结尾部分通过自动生成完成,通常用在事务的处理,安全校验,日志等上面。
2 AOP的一些名词
切面(Aspect) 一系列切点的集合
切点(PointCut) 你要切哪个方法
通知(Advice)在切点上所做的操作
目标(Target) 代理对象,用来存放通知
目标拿着通知在切点的地方去切方法
3 Aop的HelloWord
- 建立一个Java Project,添加Spring的能力
- 写一个MyCls方法,准备接下来对这个方法进行切面操作
package com.etc;
public class MyCls {
public void doit(){
//=========
System.out.println("just do it");
//==========
}
}
- 在applicationContext中配置<bean>和<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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<bean id="mycls" class="com.etc.MyCls"></bean>
<bean id="mytarget" class="com.etc.MyTarget"></bean>
<!-- aop配置, 加入aop的命名空间 -->
<aop:config>
<!-- 定义一个切面,关联一个target -->
<aop:aspect id="aspect" ref="mytarget">
<!-- 切点 -->
<aop:pointcut expression="execution (* com.etc.MyCls.*(..) )"
id="pc" />
<!-- 前置通知 关联一个切点, method关联的是target的方法-->
<aop:before pointcut-ref="pc" method="before" />
</aop:aspect>
</aop:config>
</beans>
- 定义一个MyTarget类来存放通知,MyTarget在applicationContext也要记得配置<bean>
package com.etc;
//目标
public class MyTarget {
//通知
public void before() {
System.out.println("before");
}
}
- 写测试类测试
package com.etc;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test1() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MyCls mycls = (MyCls) context.getBean("mycls");
mycls.doit();
}
}
4 通知的类型
前置before;
后置after;
环绕arounf,可以修改返回值,前置通知和后置通知都可以用环绕通知来代替;
异常after-throwing;
最终after-return;
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<bean id="mycls" class="com.etc.MyCls"></bean>
<bean id="mytarget" class="com.etc.MyTarget"></bean>
<!-- aop配置, 加入aop的命名空间 -->
<aop:config>
<!-- 定义一个切面,关联一个target -->
<aop:aspect id="aspect" ref="mytarget">
<!-- 切点 -->
<aop:pointcut expression="execution (* com.etc.MyCls.*(..) )"
id="pc" />
<!-- 前置通知 关联一个切点, method关联的是target的方法 -->
<!-- <aop:before pointcut-ref="pc" method="before" /> -->//前置
<!-- <aop:after method="after" pointcut-ref="pc" /> -->//后置
<!-- <aop:around method="around" pointcut-ref="pc" /> -->//环绕
<!-- <aop:after-throwing method="thr" pointcut-ref="pc" throwing="e"/> -->//异常
<aop:after-returning method="ret" pointcut-ref="pc" returning="r"/>//最终
</aop:aspect>
</aop:config>
</beans>
5 AOP配置事务
什么叫事务?
要不然同时成功,要不然同时失败的一组操作。
比如A转200给B,A的账户要减200,B的账户要加200,要写两行数据库代码,操作要同时成功,或同时失败。要不然A成功了,B失败了,那么银行就挣了200块,又或者A失败了,B成功了,那么银行就亏了200快。所以要设定事务。
平常做商城,购物车什么的也要添加事务
- 在applicationContext.xml中添加配置事务代码,注意dao 一般是单表操作,而我们一般多表操作都在Service,所以事务要加在Service层,
<!-- 事务管理者 -->
<bean id="myTxManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="productServiceMethods" expression="execution(*
com.etc.service.*.*(..))" />
//注意不同的项目要修改这
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
</aop:config>
//通知,spring给事务另起的一个命名空间
<tx:advice id="txAdvice" transaction-manager="myTxManager">
<tx:attributes>
<!-- 事务的传播特性 -->
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 事务的配置结束 -->
6 注解
Annotation ,将代码和配置文件融为一体,改代码的同时,改配置文件,分散在各个代码中
- 配置applicationContext
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 开启注解的支持 -->
<context:annotation-config></context:annotation-config>
<!-- 注解扫描 -->
<context:component-scan base-package="com.etc">
</context:component-scan>
</beans>
- @Component == 其他
- @Controller == action 控制器
- @Service == service
- @Repository == dao
四个注解只是名字不一样,功能都是一样的,就是将当前的类变成一个<bean>,并且将类的首字母小写作为<bean>的id。
- @Autowired 根据名字自动注入,如果有类型一样的也会自动注入,不用写get/set。
@Qualifer("helloDAO") 指明注入<bean>的id ------
要和@Autowired结合起来用
- @Resource (name="helloDAO ") 和上面两个加起来功能一样
- @Scope("singleton")//单例 ,内存中只有一份 @Scope("prototype")//原型,每次都会创建一份
- @PostConstruct //和init()方法功能相同,程序开始时调用
- @PreDestory //和destory()方法相同,程序结束时调用