zoukankan      html  css  js  c++  java
  • 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>
    
  • 相关阅读:
    c# 类型转换符的重载
    C# 串口读写
    STM32 Keil C++编写单片机程序
    C# 静态构造函数的使用
    MvvMlight 学习之 SimpleIoc
    STM32 之 DMA
    STM32 之 SysTick
    突然发现用PHP做多条件模糊查询很简单
    discuz代码转为html代码
    Discuz!开发之HTML转Discuz代码(bbcode)函数html2bbcode()
  • 原文地址:https://www.cnblogs.com/mznsndy/p/12934946.html
Copyright © 2011-2022 走看看