Spring4

  • Spring javaEE开发一站式框架
    • web层:SpringMVC
    • Service层:Spring的Bean管理(IoC)、Spring声明式事务
    • Dao层:Spring的jdbc模板。Spring的ORM模块用于整合其他的持久层框架

SpringIOC

IoC(控制反转):将对象的创建权交给Spring

作用:用于解耦,一般分为两种类型: 依赖注入(DI,应用更广泛)和依赖查找

IoC xml开发

工厂+反射+配置文件 实现程序的解耦

<?xml version="1.0" encoding="UTF-8"?>
<!--引入beans的约束-->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
 	<bean id="UserDao" class="com.m.spring4.dao.impl.UserDaoImpl"></bean>
</beans>
//创建Spring的工厂
		ApplicationContext applicationContext=new 				ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao=(UserDao)applicationContext.getBean("UserDao");
		userDao.save();

DI

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--构造方法属性注入-->
	<bean id="Car" class="com.m.spring4.dao.Car">
		<constructor-arg name="name" value="宝马"/>
		<constructor-arg name="price" value="800000"/>
	</bean>
	<!--set方法属性注入--><!--value普通属性 ref对象属性-->
 	<bean id="UserDao" class="com.m.spring4.dao.impl.UserDaoImpl" >
 		<property name="name" value="张三"/>
 		<property name="car" ref="Car"/>
 	</bean>
    
    <!--配置init 和destory 方法-->
    <bean id="" class="" init-method="init" destory-method="destory"/>
 	
 	
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<bean id="Car" class="com.m.spring4.dao.Car">
		<constructor-arg name="name" value="宝马"/>
		<constructor-arg name="price" value="800000"/>
	</bean>
	
 	<bean id="UserDao" class="com.m.spring4.dao.impl.UserDaoImpl" p:name="张三" p:car-ref="Car">
 	</bean>
 	
 	
</beans>

SpEL

SpEL的属性注入(Spring3.0之后) Spring表达式语言

语言:#{SpEL}

name value形式
value可以是 对象、对象的属性、方法或''

注入数组类型

<bean>
<!-- 数组类型 -->
		<property name="arrs">
			<list>
				<value>王东</value>
				<value>赵洪</value>
				<value>李冠希</value>
			</list>
		</property>
		
		<!-- 注入list集合 -->
		<property name="list">
			<list>
				<value>李兵</value>
				<value>赵如何</value>
				<value>邓凤</value>
			</list>
		</property>
		
		<!-- 注入set集合 -->
		<property name="set">
			<set>
				<value>aaa</value>
				<value>bbb</value>
				<value>ccc</value>
			</set>
		</property></bean>

IoC注解开发

引入约束

<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd"> 
	<!-- 使用IoC的注解开发,配置组件扫描 (扫描类上的注解)(哪些包下的类要使用注解)-->
	<context:component-scan base-package="com.m.spring4"></context:component-scan>
    <!--在没有扫描的情况下,使用属性注入的注解 @Resource@Value@Autowired@Qualifier-->
    <context:annotation-config/>
</beans>
/*
相当于在xml配置
<bean id="userDao" class="com.m.spring4.dao.impl.UserDaoImpl"></bean>
*/
@Component("userDao")
public class UserDaoImpl implements UserDao{
    /*
    注解方式设置属性的值,可以没有set方法
    	如果有set方法注解写到set方法上。
		如果没有set方法,注解写到属性上。
    */
    @value("张三")
    private String name; 
    @Autowired
    @Qualifier(value="car类的组件名")
    private Car car;
}

IoC注解详解

1.@Component(""):组件

  • 修饰一个类,将这个类交给Spring管理
  • 有三个衍生注解:@Controller (Web层) @Service (service层) @Reposition(dao层)

2.属性注入的注解

普通属性

​ @Value("") 设置普通属性的值

对象类型属性

​ @Autowired 设置对象类型的属性的值(按照类型完成属性的注入)

​ @Qualifier (value="") 为了让其按照名称完成属性的注入

​ @Resouce(name="")用于替代@Autowired+@Qualifer

3.生命周期相关

​ 初始化方法上的注解@PostConstruct

​ 销毁方法上的注解@PreDestory

​ 相当于xml中的init-method和destory-method

4.Bean作用范围

​ @Scope("singleton/prototype/request/session/globalsession")

Spring AOP

面向切面编程 Aspect Oriented Programming

采用了横向抽取机制代替了传统的纵向继承

1.Spring底层的AOP实现原理

动态代理:

​ JDK动态代理:只能对实现了接口的类产生代理

​ Cglib动态代理(类似于javassist的第三方代理技术):对没有实现接口的类产生代理对象,生成子类对象

AOP xml开发

applicationContext.xml

<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->

<!-- 配置目标对象(Target): -->
<bean id="productDao" class="com.m.spring4.demo3.ProductDaoImpl"/>
<!-- 切面类 交给Spring管理 -->
<bean id="myAspectXml" class="com.m.spring4.demo3.MyAspectXml"/>


<!-- 通过 AOP的配置对目标类产生代理-->
<aop:config>
	<!-- expression配置哪些类的那些方法需要增强 -->
	<aop:pointcut expression="execution(* com.m.spring4.demo3.ProductDaoImpl.save(..))" id="pointcut1"/>
	<aop:pointcut expression="execution(* com.m.spring4.demo3.ProductDaoImpl.delete(..))" id="pointcut2"/>
	<aop:pointcut expression="execution(* com.m.spring4.demo3.ProductDaoImpl.update(..))" id="pointcut3"/>
	
	<!-- 配置切面 -->
	<!-- 前置通知 -->
	<aop:aspect ref="myAspectXml">
		<aop:before method="checkPri" pointcut-ref="pointcut1"/>
	</aop:aspect>
	<!-- 后置通知 -->
	<aop:aspect ref="myAspectXml">
		<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
	</aop:aspect>
	<aop:aspect ref="myAspectXml">
		<aop:around method="around" pointcut-ref="pointcut3"/>
	</aop:aspect>
	
</aop:config>
</beans>


public class MyAspectXml {
	/**
	 * 前置通知-权限校验
	 */
	public void checkPri(JoinPoint joinpoint) {
		System.out.println("权限校验。。打印连接点信息"+joinpoint);
	}
	/**
	 * 后置通知-写日志
	 */
	public void writeLog(Object result) {
		System.out.println("日志记录。。返回值:"+result);
	}
	/**
	 * 环绕通知-性能监控
	 * @throws Throwable 
	 */
	public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
		System.out.println("环绕前通知。。");
		Object obj=joinpoint.proceed();//相当于执行目标程序
		System.out.println("环绕后通知。。");
		return obj;
	}
}


Spring通知类型

  • 前置通知:目标方法执行之前

​ 可以获得切入点信息

  • 后置通知:目标方法执行之后

​ 可以获得方法的返回值

  • 环绕通知:在目标方法执行之前和之后进行操作

​ 环绕通知可以阻止目标方法的执行

  • 异常抛出通知:在程序抛出异常的时候,进行操作

  • 最终通知:无论代码是否有异常,总会执行。

  • 引介通知

切入点表达式(expression)写法:

>execution([访问修饰符] 方法返回值 包名.类名.方法名(参数))
>
>通配符*
>
>..
>
>+

基于AspectJ的注解开发

<?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:context="http://www.springframework.org/schema/context"
   xmlns:aop="http://www.springframework.org/schema/aop" 
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
   	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 
   
   <!-- 在配置文件中开启注解的AOP开发 -->
   <aop:aspectj-autoproxy/>
   <!-- target -->
   <bean id="orderDao" class="com.m.spring4.demo4.OrderDao"/>
   <!-- 切面类 -->
   <bean id="myAspectAnno" class="com.m.spring4.demo4.MyAspectAnno"/>
    
    
</beans>
//切面类
@Aspect
public class MyAspectAnno {
	@Before(value="execution(* com.m.spring4.demo4.OrderDao.save(..))")
	public void before() {
		System.out.println("前置增强==");
	}
}

//使用切入点注解
@Aspect
public class MyAspectAnno {
	@Before(value="MyAspectAnno.pointcut1()")
	public void before() {
		System.out.println("前置增强==");
	}
    //切入点注解
    @Pointcut("execution(* com.m.spring4.demo4.OrderDao.save(..))")
    public void pointcut1(){}
}

注解

定义切面类的注解

​ @Aspect

通知类型

​ @Before 前置通知

​ @AfterRunning 后置通知

​ @Around 环绕通知

​ @AfterThrowing 异常抛出后通知

​ @After 最终通知

@Pointcut 定义切入点的注解

Spring的工厂类

  • BeanFactory 老版本的工厂类: 调用getBean时,才会生成Bean的实例

  • ApplicationContext 新版本的工厂类,继承了BeanFactory: 加载配置文件时就生成Bean的实例

    有两个具体的实现类

    • FileSystemApplicactionContext 加载类路径下的配置文件
    • ClassPathXmlApplicationContext 加载文件系统下的配置文件

加载多个配置文件

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("1.xml","2.xml")

在一个配置文件中引入其他配置文件

<import resource="applicationContext2.xml"/>

JDBC Template

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

	<!--配置Spring内置连接池-->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName"
			value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql:///store?useSSL=false" />
		<property name="username" value="root" />
		<property name="password" value="Gepoint" />
	</bean>
	<bean id="jdbcTemplate"
		class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource" />
	</bean>

</beans>
	<!-- 配置DBCP连接池 -->
<!--引入jar包
com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
com.springsource.org.apache.commons.pool-1.5.3.jar
-->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql:///store?useSSL=false" />
		<property name="username" value="root" />
		<property name="password" value="Gepoint" />
	</bean>

C3P0连接池

 <!-- 配置C3P0连接池 -->
	 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql:///store?useSSL=false"></property>
	 	<property name="user" value="root" />
		<property name="password" value="Gepoint" />
	 </bean>

常用方式:外部属性文件

<!--
//jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///store?useSSL=false
jdbc.username=root
jdbc.password=Gepoint
-->
<!-- 配置C3P0连接池 -->
	 <!-- 引入外部属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
	 	<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	 </bean>

Spring的事务管理

Spring事务管理API

平台事务管理器根据事务定义信息进行事务的管理,,在事务管理的过程中,产生的各种状态记录到事务状态的对象中。

PlatformTranscationManager

平台事务管理器

实现类:

DataSourceTranscationManager:底层使用jdbc管理事务

HibernateTranscationManager:底层使用hibernate管理事务

TranscationDefinition

事务定义信息

用于定义事务相关的信息:隔离级别、超时信息、传播行为、是否只读

TranscationStatus

事务的状态

用于记录在事务管理过程中,事务的状态对象。

事务的传播行为

事务应该加到业务层

事务的传播行为主要用来解决业务层方法相互调用的问题。

Spring提供了7种事务的传播行为:

事务管理

编程式事务管理

​ 1.配置平台事务管理器

​ 2.配置事务的管理模板类

​ 3.在业务层注入事务管理的模板

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
		<!-- Dao -->
	<bean id="accountDao" class="com.m.spring4.tx1.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	<!-- Service -->
	<bean id="accountService" class="com.m.spring4.tx1.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
        <!--3.在业务层中注入事务管理模板-->
		<property name="transactionTemplate" ref="transactionTemplate"/>
	</bean>

	<!-- JDBC -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
	 	<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	 </bean>
	 
	 
	 <!-- 1.配置平台事务管理器 -->
	 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	 	<property name="dataSource" ref="dataSource"/>
	 </bean>
	 <!-- 2.配置事务管理模板 -->
	 <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
	 	<property name="transactionManager" ref="transactionManager"/>
	 </bean> 
</beans>
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	//注入事务管理的模板
	private TransactionTemplate transactionTemplate;
	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}
	@Override
	public void transfer(String from,String to,Double money) {
		
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				// TODO Auto-generated method stub
				accountDao.outMoney(from, money);
				int d=1/0;
				accountDao.inMoney(to, money);
				
			}
		}) ;
		
	}

}

声明式事务管理

通过配置实现 --AOP

	 <!-- 配置平台事务管理器 -->
	 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	 	<property name="dataSource" ref="dataSource"/>
	 </bean>
	 <!-- 配置事务的增强 -->
	 <tx:advice id="txAdvice" transaction-manager="transactionManager">
	 	<tx:attributes>
	 		<tx:method name="*" propagation="REQUIRED"/>
	 	</tx:attributes>
	 </tx:advice>
	 <!-- AOP的配置 -->
	 <aop:config>
	 	<aop:pointcut expression="execution(* com.m.spring4.tx1.AccountServiceImpl.*(..))" id="pointcut1"/>
	 	<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
	 </aop:config>
posted @ 2020-05-22 07:26  赵钱富贵  阅读(284)  评论(0编辑  收藏  举报