Spring

Spring介绍

简介

  • Spring框架是一个帮我们管理对象的容器,可以看做是对象的管家。
  • Spring一站式框架:正是由于Spring框架的性质是属于容器性质的,容器中装什么对象,就有什么功能,所以可以一站式,spring不仅不排斥其他框架,还可以帮其他框架管理对象

spring中名词解释

  • IOC(inverse of Control):控制反转
    将对象的创建方式反转了,从由自己创建,反转为由spring容器创建,以前对象的创建和维护以及依赖关系都由我们自己来做,现在可以将这些工作交给程序来做
  • DI(dependency injection):依赖注入
    实现IOC需要DI支持
    注入方式:set注入、构造注入、字段注入
    注入类型:8大数据类型、应用数据类型

Spring搭建

步骤:

  1. 导包
  2. 创建实体类
  3. 创建配置文件(文件名和位置无要求,但是最好名为applicationContext.xml,并且放置在src下
    【】导入约束
    【】将实体类的对象交给spring容器管理
//name:spring创建对象的名称     class:对应实体类的全类名
<bean name="user" class=""></bean>

测试代码:

//创建容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中取出对象
User u = ac.getBean("user")

Spring的配置详解

bean元素

/*
    name:spring创建对象的名称     
    class:对应实体类的全类名
    scope:
          singleton(默认值):创建单例对象,在spring容器中只会存在一个实例
          prototype:多例原型,每次再获得时才会被创建,而且每次得到的对象都是新的
          init-method(填初始化方法的方法名):spring会在对象创建后立即调用该方法 
          destory-method(填销毁方法的方法名):在spring容器关闭并销毁所有对象前调用该方法
*/
<bean name="user" class="" scope="singleton" init-method="" destory-method="" ></bean> 

Spring创建对象的方式

  • 空参构造方式(调用无参的构造方法)
  • 静态工厂方式(了解)
  • 实例工厂方式(了解)

spring的分模块配置

//resource:另一个xml配置文件的路径
<import resource="" />

Spring的属性注入

set方法注入

<bean name="user" class"">
//值类型注入
//将User对象中名为name的属性值赋值为张三
    <property name="name" value="张三"></property>
    <property name="age" value="18"></property>
    
//引用类型注入
//将对象名为car的对象赋值给User对象中的Car类型的引用变量
    <property name="car" ref="car"></property>
</bean>

构造函数注入

<bean>
/*
    name:构造函数的函数名
    index:构造函数的参数索引
    type:参数类型
*/
<constructor-arg name="" index="" type=""></constractor>
<constructor-arg name="" index="" ref=""></constractor>
</bean>

spl注入

复杂类型注入

  • 数组
<property name="array">
    <array>
        <value>Tom</value>
        <value>jery</value>
        <ref bean="car  ">
    </array>
</property>
  • List
<property name="list">
    <list>
        <value>Tom</value>
        <value>jery</value>
        <ref bean="car  ">
    </list>
</property>
  • Map
<property name="map">
    <map>
        <entry key="" value=""></entry>
        <entry key-ref="" value-ref=""></entry>
    </map>
</property>
  • Properties
<property name="properties">
    <props>
        <prop key="driverClass">com.jdbc.mysql.Driver</prop>
    </props>
</property>

Spring 的注解配置

  • 步骤:
  1. 导包
  2. 在主配置文件中导入约束
  3. 在配置文件中开启使用注解
//指定扫描cn.itcast.bean包下的注解
//注意:扫描包时,会自动扫描指定包的子孙包
<context:component-scan base-package="cn.itcast.bean"></context:component-scan>
  • 在类中完成注解配置
  1. 将对象注册到容器中
//四个注解效果一样
@Component("user")
//@Service("user1")         service层注解
//@Controller("user2")		web层注解
//@Repository("user3")		dao层注解
@Scope(scopeName="prototype")//指定对象作用范围
public class User {

	@Value("tom")             //通过反射的Field赋值,破坏了封装性
	private String name;

	private Integer age;
	//@Autowired       //自动装配
	//问题:如果匹配多个类型一致的对象,将无法选择注入哪一个对象
	//@Qualifier("car")//使用Qualifier注解告诉spring容器自动装配哪个名称的对象
	
	@Resource(name="car")//手动注入
	private Car car;   
	
	@Value("tom")             //通过set方法赋值
	public void setName(String name) {
		this.name = name;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public void setCar(Car car) {
		this.car = car;
	}

	@PostConstruct   //初始化方法,在对象被创建后调用
	public void init(){
		System.out.println("我是初始化方法");
	}
	
	@PreDestroy      //销毁方法,在销毁之前调用
	public void destory(){
		System.out.println("我是销毁方法");
	}
	
}

  • spring与Junit整合测试
  1. 导包
  2. 配置注解
//帮我们创建容器
@Runwith(SpringJunit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml");
@Test
public void fun(){

}

Spring中的AOP

  • AOP思想介绍:纵向重复,横向抽取(如过滤器解决乱码问题)
  • Spring中AOP概念:以前需要使用动态代理产生代理对象,现在spring能够帮我们生成代理对象
  • Spring实现AOP的原理:
  1. 动态代理优先(被代理对象必须要实现接口才能产生代理对象)
  2. 使用cglib代理(不要接口,可以对任何类进行代理。代理的原理是对目标对象进行继承代理。如果目标对象被final修饰,则不能完成代理)
  • AOP中的名词
  1. Joinpoint(连接点):目标对象中所有可以被增强的方法。
  2. Pointcut(切入点):目标对象已经增强的方法。
  3. Advice(通知/增强):增强的代码
  4. Target(目标对象):被代理对象
  5. weaving(织入):将通知应用到切入点的过程
  6. Proxy(代理):将通织入到目标对象后生成的代理对象
  7. aspect(切面):切入点+通知

#Spring中的AOP演示.

xml配置

  1. 导包
  2. 准备目标对象
public class UserServiceImpl implements UserService {

	@Override
	public void add() {

		System.out.println("添加");
	}

	@Override
	public void delete() {
		System.out.println("删除");

	}

	@Override
	public void update() {
		System.out.println("更新");

	}

	@Override
	public void find() {
		System.out.println("查找");

	}

}
  1. 准备通知
public class MyAdvice {

	public void before(){
		System.out.println("这是前置通知");
	}
	public void around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("这是环绕通知的前半部分");
		pjp.proceed();
		System.out.println("这是环绕通知的后半部分");
	}
	public void after(){
		System.out.println("这是after后置通知");
	}
	public void afterRunning(){
		System.out.println("这是afterRunning后置通知");
	}
	public void afterException(){
		System.out.println("出现异常了");
	}
}
  1. 配置织入
<!-- 配置目标对象 -->
<bean name="userService" class="cn.itcast.service.UserServiceImpl"></bean>

<!-- 配置通知对象 -->
<bean name="myAdvice" class="cn.itcast.d_springaop.MyAdvice"></bean>

<!-- 将通知织入切点 -->
<aop:config>

	<!-- public void cn.itcast.service.UserServiceImpl.add() -->
	<!-- void cn.itcast.service.UserServiceImpl.add() -->
	<!-- * cn.itcast.service.UserServiceImpl.add() -->
	<!-- * cn.itcast.service.UserServiceImpl.*() -->
	<!-- * cn.itcast.service.UserServiceImpl.*(..) -->
	<!-- * cn.itcast.service.*ServiceImpl.*(..) -->
	<!-- * cn.itcast.service..*ServiceImpl.*(..) -->
	<aop:pointcut expression="* cn.itcast.service..*ServiceImpl.*(..)" id="pc"/>
	
	<aop:aspect ref="myAdvice">
		<aop:before method="before" pointcut-ref="pc"/>
		<aop:after method="after" pointcut-ref="pc"/>
		<aop:around method="around" pointcut-ref="pc"/>
		<aop:after-returning method="afterRunning" pointcut-ref="pc"/>
		<aop:after-throwing method="afterException" pointcut-ref="pc"/>
	</aop:aspect>
</aop:config>

注解配置

  1. 导包
  2. xml中配置通知对象和目标对象,并在xml中开启使用注解
<!-- 配置目标对象 -->
<bean name="userService" class="cn.itcast.service.UserServiceImpl"></bean>

<!-- 配置通知对象 -->
<bean name="myAdvice" class="cn.itcast.e_annotationaop.MyAdvice"></bean>

<!-- 开启使用注解完成织入 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  1. 在通知类中使用注解
@Aspect  //表示该类是一个通知类
public class MyAdvice {

	@Pointcut("execution(* cn.itcast.service.*ServiceImpl.*(..))")
	public void pc(){};
	
	@Before("MyAdvice.pc()")    
	public void before(){
		System.out.println("这是前置通知");
	}
	
	@Around("MyAdvice.pc()")
	public void around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("这是环绕通知的前半部分");
		pjp.proceed();
		System.out.println("这是环绕通知的后半部分");
	}
	@After("MyAdvice.pc()")
	public void after(){
		System.out.println("这是after后置通知");
	}
	@AfterReturning("MyAdvice.pc()")
	public void afterRunning(){
		System.out.println("这是afterRunning后置通知");
	}
	@AfterThrowing("MyAdvice.pc()")
	public void afterException(){
		System.out.println("出现异常了");
	}
}

Spring管理事物的属性介绍

  • 事物的隔离级别
  1. 读未提交
  2. 读已提交
  3. 可重复读
  4. 串行化
  • 是否只读
  1. true(只读)
  2. false(可操作)
  • 事物的传播行为:选择PROPAGATION_REQUIRED(支持当前事物,如果不存在就新建一个)即可。

  • Spring整合jdbc事物
    dao实现类(继承JdbcDaoSupport类)

 public class AccountUserDaoImpl extends JdbcDaoSupport implements AccountUserDao {

	public void increase(Integer id,double money) {
		String sql="update account set money=money+? where id=?";
		//直接调用父类中的getJdbcTemplate方法得到jdbc模板对象,然后调用模板对象中的方法操作数据库
		getJdbcTemplate().update(sql, money,id);
	}

	public void decrease(Integer id,double money) {

		String sql="update account set money=money-? where id=?";
		getJdbcTemplate().update(sql, money,id);
	}

}

service实现类

public class AccountServiceImpl implements AccountService {
	private AccountUserDao accountDao;
	
	public void transfer(final Integer form, final Integer to, final double money) {

				accountDao.decrease(form, money);
				accountDao.increase(to, money);
	}
	
	public void setAccountDao(AccountUserDao accountDao) {
		this.accountDao = accountDao;
	}
}

xml配置文件

<!-- 指定db.properties文件的位置 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 配置连接池 -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
	<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="user" value="${jdbc.user}"></property>
	<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- 事务管理核心对象 -->
	<bean name="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<bean name="accountDao" class="cn.itcast.dao.AccountUserDaoImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<bean name="accountService" class="cn.itcast.service.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"></property>
	</bean>
	
	<!-- 配置通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transfer" isolation="REPEATABLE_READ" read-only="false" propagation="REQUIRED" />
			 <!-- 如果想对所有方法进行增强则采用如下配置,但是注意:所有方法都必须遵循此命名规则 -->
			<tx:method name="save*" isolation="REPEATABLE_READ" read-only="false" propagation="REQUIRED" />
			<tx:method name="update*" isolation="REPEATABLE_READ" read-only="false" propagation="REQUIRED" />
			<tx:method name="delete*" isolation="REPEATABLE_READ" read-only="false" propagation="REQUIRED" />
			<tx:method name="get*" isolation="REPEATABLE_READ" read-only="true" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>

	<!-- 将通知织入到目标对象 -->

	<aop:config>
		<aop:pointcut
			expression="execution(* cn.itcast.service.*ServiceImpl.transfer(..))"
			id="txPc" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
	</aop:config>

使用注解配置jdbc事物:
xml文件

<!-- 指定db.properties文件的位置 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 配置连接池 -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- 事务管理核心对象 -->
	<bean name="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<bean name="accountDao" class="cn.itcast.dao.AccountUserDaoImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<bean name="accountService" class="cn.itcast.service.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"></property>
	</bean>
	
	<!-- 开启使用注解管理aop事物 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>

service实现类

//可以将注解配置到类上,对类中的所有方法都起作用,若类中某一方法的配置有所不同,可以在此方法上重写一个仅对此方法有用的配置
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
public class AccountServiceImpl implements AccountService {

	private AccountUserDao accountDao;

	public void transfer(final Integer form, final Integer to, final double money) {

		accountDao.decrease(form, money);
		accountDao.increase(to, money);

	}
	@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=true)
	public User get(int id){
	    User u=accountDao.get(id);
	}

	public void setAccountDao(AccountUserDao accountDao) {
		this.accountDao = accountDao;
	}
	
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值