Spring
IOC:Inverse Of Control反转控制
将我们创建对象的方式反转了
以前对象的创建是有我们开发人员自己维护,包括依赖关系也是自己注入。
使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入。
DI:Dependency Injection依赖注入
实现IOC思想需要 DI做支持。
注入方式:set方法
构造方法
字段注入
注入类型:
值类型注入
引用类型注入
scope属性
singleton(默认值):单例对象,被标识为单例的对象在spring容器中只会存在一个实例。即在向容器中要对象时,得到的都是同一个对象。
//1.创建容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("cn/it/applicationContext.xml");
//2.向容器中要“user"对象
User u=(User)ac.getBean("user");
User u2=(User)ac.getBean("user");
User u3=(User)ac.getBean("user");
System.out.println(u2==u3);//打印的结果为true;
prototype:多例原型,被标识为多例的对象,每次再获得才会创建。每次创建都是新的对象。
多例时上面的打印结果为false。
依赖注入的三种方式:
setter注入:(多数用这个)
<bean id="role2" class="com.ssm.pojo.Role">
<property name="roleName" value="高级工程师"/>
<property name="note" value="重要人员"/>
</bean>
构造器注入:
<bean id="role1" class="com.ssm.pojo.Role">
<constructor-arg index="0" value="总经理"/>
<constructor-arg index="1" value="公司总经理"/>
</bean>
在spring中,提供了两种方式来让Spring IoC容器发现Bean
组件扫描和自动装配
1.组件扫描:
<context:component-scan base-package="com.taoxiuxia.service.impl" />
//扫描这个包中的类及子孙类
那么就可以在对应的类上加上@Component(“你想加到容器中的名字”)
相当于<bean name="user" class="类名"
。利用Component注解把类加入到容器中。
2.自动装配
@AutoWired
问题:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象。
值类型注入两种方式:
@Value("tom")
private String name;
上面这种是通过反射的Field赋值
@Value("tom")
public void setName(String name){
this.name=name;
}
上面这种是通过set方法赋值。
引用类型注入
@Autowired //自动装配
private Car car;
@Autowired
//问题:匹配多个类型一致的对象,将无法选择具体注入哪一个对象
@Qualifier("car2") //@Qualifier注解告诉spring容器自动装配哪个名称的对象。
private Car car;
@Resource(name="car"); //手动注入,指定注入哪个名称的对象。
private Car car;
@PostConstruct //在对象被创建后调用,init-method
@PreDestroy //在销毁之前调用,destroy-method
spring能够为容器中管理的对象生成动态代理。
以前我们要使用动态代理,我们需要自己调用下面这个方法,生成代理对象
Proxy.newProxyInstance(xx,xx,xx)
spring能够帮我们生成代理对象。
spring实现aop的原理
1.动态代理(优先)(被代理对象必须要实现接口,才能产生代理对象,如果没有借口,将不能使用动态代理。)
2.cglib代理(没有接口)(第三方代理技术,cgilib代理,代理的原理是对 目标对象进行继承代理。如果目标对象被final修饰,那么该类无法被cglib代理。)
aop的名词解释:
aop的准备工作
导包
准备目标对象
准备通知
配置进行织入,将通知织入目标对象中。、
通知
前置通知:目标方法运行之前调用
后置通知(如果出现异常不会调用):在目标方法运行之后调用
环绕通知:在目标方法之前和之后都调用
异常拦截通知:如果出现异常,就会调用
后置通知(无论是否出现异常都会调用):在目标方法运行之后调用。
切入点表达式:
execution(表达式)
表达式:
[方法访问修饰符] 方法返回值 包名.类名.方法名(方法的参数)
*表示所有
*()表示对方法是什么不做要求
*(..)表示对方法的参数不做任何要求
public * cn.itcast.spring.dao..(..)
* cn.itcast.spring.dao..(..)
* cn.itcast.spring.dao.UserDao+.*(..)
* cn.itcast.spring.dao...(..)
aop配置
1.编写一个切面类
public class UserService{
// 前置增强
public void before(){
System.out.println("前置增强===========");
}
}
2.配置完成增强
<!-- 配置切面类 -->
<bean id="userService" class="cn.itcast.spring.demo3.UserService"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut expression="execution(*
cn.itcast.spring.demo3.OrderDao.save(..))" id="pointcut1"/>
<!-- 配置切面 -->
<!--这里的ref引用的就是前面的bean的name pointcut-ref就是前面写的切入表达式-->
<aop:aspect ref="userService">
<aop:before method="before" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
针对以上的配置,我们写个测试类
public class Demo{
@Resource(name="userService")//配置生成代理对象
private UserService us;
@Test
public void fun1(){
us.save();//这里打印的结果就是before方法的打印语句。相当于在方法执行之前执行了before方法。根据前置通知的定义。
}
}
其他的配置增强
配置织入
<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut expression="execution(*
cn.itcast.spring.demo3.*Dao.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(*
cn.itcast.spring.demo3.*Dao.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(*
cn.itcast.spring.demo3.*Dao.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(*
cn.itcast.spring.demo3.*Dao.find(..))" id="pointcut4"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="afterReturing"
pointcut-ref="pointcut2"/>
<aop:around method="around" pointcut-ref="pointcut3"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4"/>
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
配置事务通知
spring事务管理-xml配置aop事务
beans:最基本
context:读取properties配置
aop:配置aop
tx:配置事务通知
isolation=”DEFAULT” 隔离级别
propagation=”REQUIRED” 传播行为
read-only=”false” 只读
timeout=”-1” 过期时间
rollback-for=”” -Exception
no-rollback-for=”” +Exception
1.xml方式配置
<tx:advice transation-manager="transationManager">
<tx:attributes>
<tx:method name="save*" isolationManager="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
2.注解配置
<!-- 开启使用注解管理aop事务 -->
<tx:annotation-driven/>
在函数上加上
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
public void transfer(...){}