Day_01 Spring入门
<!-- id是bean的标识符,必须唯一,如果没有配置id,name默认为标识符 如果配置了id,有配置了name,那么name为别名 name可以设置多个别名,分隔符可以是空格 逗号 分号 class是bean的全限定名,即包名加类名 如果不配置id和name,那么可以根据applicationContext.getbean(Class)获取对象, scope:bean的作用域, 取值:singleton:单例的,整个容器只产生一个对象,默认是单例 prototype:原型,每次获取bean都创建一个新对象 request:每次请求时创建一个新的对象 session:在一个会话范围内只产生一个对象 application:在应用范围内是一个对象 autowire:自动装配 用于简化spring的配置 取值:byname:根据名称(根据set方法中set后面的内容)去查找相应的bean,发现了则装载上 bytype:根据类型自动装配,不用去管id,但同一种类型的bean只能有一个,f否则报错 constructor,当通过构造器注入实例化bean时,装配构造方法 --> <bean id="userMysqlDaoImpl" class="com.wang.dao.impl.UserMysqlDaoImpl"></bean> <bean id="userOracleDaoImpl" class="com.wang.dao.impl.UserOracleDaoImpl"></bean> <bean id="service" class="com.wang.service.UserService"> <property name="userDao" ref="userOracleDaoImpl"></property> </bean> |
今天学习内容
l 学习哪些Spring框架中技术
l 快速了解Spring框架搭建
l 快速测试Spring框架
l Spring框架中IOC和DI概念
1、学习Spring框架中哪些技术
l Spring中IOC
l Spring中AOP
l Spring中DataAccess
l Spring中Web开发,SpringMVC
l Spring中注解
l Spring配置文件
2、Spring框架搭建
l 导入Spring包
Ø spring.jar:包含很多Spring框架功能模块包,如:orm,web,aop
Ø common-logging.jar:spring框架在运行BeanFacotry时候需要的依赖包(简单理解就是运行Spring框架的依赖包)
l Spring的整体功能体系架构图
l Spring IOC概念
Ø 所有的Java类(不管是JDK库中Java类,还是你自己定义Java类)都可以利用Spring框架来new它们的实例化对象
Ø Spring框架完成对Java类的初始化对象工作
l 配置spring.xml文件,其实spring.xml文件就是Spring框架中的容器
<?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"> <import resource="spring-day01.xml"/> <!- import:分成小类-à </beans>
<?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="person" class="com.gxa.spring.day01.Person"></bean><!—配置java对象-à </beans> |
l 测试Spring框架的应用程序,使用BeanFactory来完成
package com.anhen.day01; public class Person { private String name; public void setName(String name){ this.name = name; }
public String getName(){ return name; }
} |
package com.gxa.spring.test01;
import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.gxa.spring.day01.Person;
public class Test01 {
@Test public void m01() { /** * 运行Spring框架需要用到BeanFactory * 1.BeanFactory帮助我们启动IOC容器 * 2.帮助我们找到需要实例化Java对象 */ BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring.xml"); Person person = (Person) beanFactory.getBean("person"); person.setName("Hello World"); System.out.println(person.getName()); } }
|
3、Spring的IOC和DI
l Spring中IOC和DI其实概念一样
l IOC控制反转,所有的Java类的初始化工作扔给Spring框架。Spring框架充分利用Java反射
l DI依赖注入,一个Java类如果依赖其他Java类,则此类依赖另一个Java类的初始化工作也扔给Spring框架来完成
Ø 通过从MVC分层开发角度去理解一下DI
Ø Controller控制器依赖Service,假设整个Web开发过程中我们使用Spring框架,则Serivce的初始化工作时Controller不用关心Service对象是如何创建的,Service创建过程扔给Spring框架
l DI和IOC程序实现的原理是什么
4、Spring充当管理作用
Day_02 Spring基础部分的学习
今天学习内容
l 了解BeanFactory中的getBean方法
l Spring依赖注入的两种方式(构造方法注入和setter方式注入)
l p-namespace方式配置(用于简化<property>)
l properties属性文件配置方式
l 集合对象配置方式
l Bean scopes作用域(单例作用域和原生作用域)
l Spring中Annotation注解使用
1、BeanFactory中genBean方法
l getBean(String name): 获取对象,但是需要类型转换
BeanFactorybeanFactory = new ClassPathXmlApplicationContext("spring.xml");
Person person = (Person) beanFactory.getBean("person");//spring框架已经实例化了类
l getBean(String name, Class<T> clazz):获取对象,无需类型转换
PetServiceImpl pet = applicationContext.getBean("petService",PetServiceImpl.class);
l BeanFactory是获取注入到Spring容器中对象的工厂类。ApplicationContext是BeanFactory子接口
l 注意
Ø 如果使用getBean(String name, Class<T> clazz)方法一定要关注Spring框架版本
Ø 如果使用spring.4.0.3版本导包要包含(spring-core.jar,spring-beans.jar, spring-context.jar, spring-expression.jar, common-logging.jar)
2、Spring依赖注入方式
l 构造方法注入
Ø 先定义好依赖对象
Ø 再去定义构造方法,然后在构造方法的参数中去为依赖对象赋值
Ø 在配置文件中<constructor-arg>(通过构造函数注入)
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
</beans> |
public class PetServiceImpl { private PetDaoImpl petDao;//依赖对象
public PetServiceImpl(PetDaoImpl petDao){//构造方法 this.petDao = petDao; }
public void selectPet(){ petDao.selectPet01(); }
} |
l 设置(Setter)方式注入
Ø 先定义好依赖对象
Ø 给依赖对象只添加setter方法
Ø 在配置文件中使用<property>(通过setter对应的方法注入)标签就OK了
<?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="person" class="com.anhen.day01.Person"></bean>
<bean id="petService" class="com.anhen.day01.PetServiceImpl"> <property name="petDao" ref="petDao"></property> <property name="itemDao" ref="itemDao"></property> </bean> <bean id="petDao" class="com.anhen.day01.PetDaoImpl"></bean> <bean id="itemDao" class="com.anhen.day01.ItemDaoImpl"></bean> </beans> |
public class PetServiceImpl {
private PetDaoImpl petDao;//依赖对象== PetDaoImpl petDao=new PetDaoImpl();(实例化由配置文件完成) private ItemDaoImpl itemDao;//依赖对象== ItemDaoImpl itemDao =new ItemDaoImpl ();(实例化由配置文件完成) //set方式注入 public void setPetDao(PetDaoImpl petDao){//没有此set方法则不能依赖注入 this.petDao = petDao; }
public void setItemDao(ItemDaoImpl itemDao) {//没有此set方法则不能依赖注入 this.itemDao = itemDao; }
public void selectPet(){ petDao.selectPet();//调用的PetDaoImpl类中的方法 itemDao.selectItem();//调用的ItemDaoImpl类中的方法 }
} |
3、p-namespace配置方式
l 主要去简化<property>标签的配置
l 要使用p-namespace需要在整个配置文件声明部分加入p-namespace的XMLSchema定义
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
</beans> |
4、properties属性文件配置(数据库配置文件)
l <bean class=”org.springframework.beans.factory.config.PropertyPlaceholderConfiguer”>来解析Java中属性文件
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="jdbc.properties"></property> </bean>
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
<bean id="dbConnection" class="com.gxa.spring.day02.DBConnection" p:username="${mysql.username}" p:password="${mysql.password}" p:driver="${mysql.driver}"></bean>
</beans> |
l <context:property-placeholder location=”jdbc.properties”>来解析Java中属性文件
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
<bean id="dbConnection" class="com.gxa.spring.day02.DBConnection" p:username="${mysql.username}" p:password="${mysql.password}" p:driver="${mysql.driver}"></bean>
</beans> |
5、集合对象的配置
l <list>,<Map>,<Set>,<Props>
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="jdbc.properties"></property> </bean>
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
<bean id="dbConnection" class="com.gxa.spring.day02.DBConnection" p:username="${mysql.username}" p:password="${mysql.password}" p:driver="${mysql.driver}"></bean>
<bean id="collectionsSpring" class="com.gxa.spring.day02.CollectionsSpring" scope="prototype"> <property name="list"> <list> <value>Hello World</value> <ref bean="dbConnection"/> </list> </property> <property name="map"> <map> <entry key="key01" value="Hello World"></entry> <entry key="key02" value-ref="dbConnection"></entry> </map> </property> <property name="set"> <set> <value>Hello World</value> <ref bean="dbConnection"/> </set> </property> <property name="props"> <props> <prop key="key01">Hello World</prop> <prop key="key02">liuyang</prop> </props> </property> </bean>
</beans> |
package com.gxa.spring.day02;
import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;
public class CollectionsSpring { private List<?> list; private Map<String,?> map; private Set<?> set; private Properties props;
public void setList(List<?> list) { this.list = list; }
public void setMap(Map<String, ?> map) { this.map = map; }
public void setSet(Set<?> set) { this.set = set; }
public void setProps(Properties props) { this.props = props; }
public void showList() { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } }
public void showMap() { System.out.println(map); }
public void showSet() { Iterator<?> iterator = set.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } }
public void showProps() { Enumeration<?> enumeration = props.propertyNames(); while(enumeration.hasMoreElements()) { System.out.println(props.getProperty(enumeration.nextElement().toString())); } } }
|
package com.gxa.spring.test02;
import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.gxa.spring.day02.CollectionsSpring; import com.gxa.spring.day02.DBConnection; import com.gxa.spring.day02.Person; import com.gxa.spring.day02.PetServiceImpl;
public class Test01 {
@Test public void m04() { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); CollectionsSpring collectionsSpring = context.getBean("collectionsSpring", CollectionsSpring.class); collectionsSpring.showList(); collectionsSpring.showMap(); collectionsSpring.showSet(); collectionsSpring.showProps(); }
} |
6、Bean Scopes作用域
l Singleton:单例作用域,Spring容器初始化对象只有唯一个(默认)
l Prototype:原生作用域,每次调用Spring容器的getBean方法都会重新产生一个新的对象
l Request
l Session
l Global Session
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="collectionsSpring" class="com.gxa.spring.day02.CollectionsSpring" scope="prototype"> <property name="list"> <list> <value>Hello World</value> <ref bean="dbConnection"/> </list> </property> <property name="map"> <map> <entry key="key01" value="Hello World"></entry> <entry key="key02" value-ref="dbConnection"></entry> </map> </property> <property name="set"> <set> <value>Hello World</value> <ref bean="dbConnection"/> </set> </property> <property name="props"> <props> <prop key="key01">Hello World</prop> <prop key="key02">liuyang</prop> </props> </property> </bean>
</beans> |
package com.gxa.spring.test02;
import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.gxa.spring.day02.CollectionsSpring; import com.gxa.spring.day02.DBConnection; import com.gxa.spring.day02.Person; import com.gxa.spring.day02.PetServiceImpl;
public class Test01 {
@Test public void m05() { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); CollectionsSpring collectionsSpring01 = context.getBean("collectionsSpring", CollectionsSpring.class); CollectionsSpring collectionsSpring02 = context.getBean("collectionsSpring", CollectionsSpring.class); System.out.println(collectionsSpring01.hashCode()); System.out.println(collectionsSpring02.hashCode()); }
} |
7、Spring的Annotation
l Spring的注解是在Spring2.5的版本中引入的,目的简化XML配置
l Spring常用的注解
Ø @Component
Ø @Autowired
Ø @Qualifier
Ø @Scope
Ø @Controller
Ø @Service
Ø @Repository
8、@Component注解
l @Component主要用于将一个Java类注入到Spring框架中,它相当于XML配置文件中的<bean id=”xxx” class=”xxx”/>
l 当使用了Spring注解后,我们需要在配置文件中添加<context:component-scan/>来扫描添加了注解的类,这样子声明注解的类才能起作用
l 同时需要关注Spring框架需要加入的包【很重要】
Ø common-logging.jar
Ø spring-core-4.0.3.jar
Ø spring-context-4.0.3.jar
Ø spring-beans-4.0.3.jar
Ø spring-expression-4.0.3.jar
Ø spring-aop-4.0.3.jar【在使用<context:component-scan/>需要导入此包】
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.gxa.spring.day02"></context:component-scan>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="jdbc.properties"></property> </bean>
<bean id="petService" class="com.gxa.spring.day02.PetServiceImpl"> <constructor-arg name="petDao" ref="petDao"></constructor-arg> </bean>
<bean id="petDao" class="com.gxa.spring.day02.PetDaoImpl"></bean>
<bean id="person" class="com.gxa.spring.day02.Person" p:petDao-ref="petDao"></bean>
<bean id="dbConnection" class="com.gxa.spring.day02.DBConnection" p:username="${mysql.username}" p:password="${mysql.password}" p:driver="${mysql.driver}"></bean>
<bean id="collectionsSpring" class="com.gxa.spring.day02.CollectionsSpring" scope="prototype"> <property name="list"> <list> <value>Hello World</value> <ref bean="dbConnection"/> </list> </property> <property name="map"> <map> <entry key="key01" value="Hello World"></entry> <entry key="key02" value-ref="dbConnection"></entry> </map> </property> <property name="set"> <set> <value>Hello World</value> <ref bean="dbConnection"/> </set> </property> <property name="props"> <props> <prop key="key01">Hello World</prop> <prop key="key02">liuyang</prop> </props> </property> </bean>
</beans> |
package com.gxa.spring.day02;
import org.springframework.stereotype.Component;
@Component public class StudentAnnotation { } /*===============================================================================================================*/ package com.gxa.spring.test;
import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.gxa.spring.day02.StudentAnnotation;
public class Test02 {
@Test public void m06() { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); StudentAnnotation studentAnnotation = context.getBean("studentAnnotation", StudentAnnotation.class); System.out.println(studentAnnotation.hashCode()); }
} |
l 除了@Component注解,Spring容器提供了3个功能和@Component注解等同。它们分别是用于对Dao,Service及Web层的Controller进行注解
Ø @Repository:用于对Dao实现类注解
Ø @Service:用于对Service实现类注解
Ø @Controller:用于对Controller实现类注解
9、@Autowired注解
l Spring2.5引入了@Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作
l Spring通过@Autowired注解实现Bean之间的依赖关系
package com.gxa.spring.day02;
import org.springframework.stereotype.Component;
@Component public class TeacherAnnotation { public void getTeacherName() { System.out.println("===刘老师好==="); } } /*===============================================================================================================*/ package com.gxa.spring.day02;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;
@Component public class StudentAnnotation {
/** * 通过Autowired来自动装备Student所依赖的对象 * 无需创建setter方法 * 无需编写XML配置文件中<property/> */ @Autowired private TeacherAnnotation teacherAnnotation;
public void showTeacher() { teacherAnnotation.getTeacherName(); } }
|
l @Autowired(required = false), 告诉 Spring:在找不到匹配 Bean 时也不报错
package com.gxa.spring.day02;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;
@Component public class StudentAnnotation {
/** * 注意TeamAnnotation没有加入@Component * 当StudentAnnotation依赖TeamAnnotation会报错 * 但是如果加入@Autowired(required=false)就不会报错 */ @Autowired(required=false) private TeamAnnotation teamAnnotation;
public void showTeacher() { teacherAnnotation.getTeacherName(); } }
|
10、@Qualifier指定注入Bean的名称
l 如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定注入的Bean名称
package com.gxaedu.bean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component;
@Component public class Computer { @Autowired @Qualifier("storage01") private Storage storage; public void m01() { storage.show(); } } /*===============================================================================================================*/ package com.gxaedu.bean;
import org.springframework.stereotype.Component;
@Component("storage01") public class Storage { //此类是在com.gxaedu.bean下的Storage public void show() { System.out.println("东芝硬盘"); } } /*===============================================================================================================*/ package com.gxaedu.test;
import org.springframework.stereotype.Component;
@Component public class Storage { //此类是在com.gxaedu.test下的Storage
} |
11、@Qualifier为方法指定注入Bean名称
package com.gxa.spring.day02;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component;
@Component public class StudentAnnotation {
private CourseAnnotation courseAnnotation;
/** * @Autowired来自动装备构造方法里面的对象 * @Qualifier来指定依赖对象的bean * @param courseAnnotation */ @Autowired public StudentAnnotation(@Qualifier("course") CourseAnnotation courseAnnotation) { this.courseAnnotation = courseAnnotation; }
public void showCourse() { System.out.println(courseAnnotation.hashCode()); } } |
12、@Scope注解来显式指定Bean作用范围
@Scope("prototype") @Component public class Car { } |
Day_03 Spring的AOP, DataAccess介绍
今天学习内容
l Spring的AOP介绍(包括XML方式配置和注解方式配置)
l Spring的DataAccess介绍,重点对JDBC整合
l Spring的事务管理
1、Spring AOP面向切面编程入门
l AOP为Aspect Oriented Programming的缩写,含义:面向切面的切面。它是对OOP的有力补充。
l 主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
l 主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来
2、有关Spring中AOP的概念
l 切面,Aspect:关注点
l 连接点,Join Point:程序执行过程中的某一点
l 建议,Advice:AOP框架在特定的连接点上执行的动作
l 切入点,Pointcut:一系列连接点的集合
l 目标对象,Target object:要被代理的对象
l AOP代理,AOP Proxy:AOP框架创建的对象,Spring中的AOP代理包含JDK动态代理和CGLIB代理,前者为接口代理(实现接口的目标对象代理),后者为类代理
l 引入,Introduction:简单说就是AOP中的方法
3、建议的分类
l Before Advice
l After Advice
l Around Advice
4、简单日志记录AOP实现
l 创建一个记录日志的AOP
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;
@Aspect public class LogAop {
@Before("execution(public void com.spring.dao.impl.StudentDaoImpl.*(..))") public void logBefore() { System.out.println("方法执行之前转载日志"); } } |
l 创建一个StudentDao接口
package com.spring.dao;
public interface StudentDao { public void insert(); } |
l 创建实现StudentDao接口的类
package com.spring.dao.impl;
import com.spring.dao.StudentDao;
public class StudentDaoImpl implements StudentDao {
@Override public void insert() { System.out.println("method insert"); }
} |
l 创建一个Service类
package com.spring.services;
import com.spring.dao.StudentDao;
public class StudentServices { private StudentDao dao;
public void setDao(StudentDao dao) { this.dao = dao; }
public void insert() { dao.insert(); } } |
l 创建一个JUnit测试类
package com.spring.junit;
import static org.junit.Assert.*;
import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.dao.StudentDao; import com.spring.services.StudentServices;
public class Test_AOP {
@Test public void testInsert() { ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); StudentServices ss = (StudentServices) ac.getBean("studentServices"); ss.insert(); }
} |
l 创建bean-aop-annotation.xml文件,此文件开启一个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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="studentServices" class="com.spring.services.StudentServices"> <property name="dao" ref="studentDao"></property> </bean>
<bean id="studentDao" class="com.spring.dao.impl.StudentDaoImpl"> </bean>
<bean id="logAop" class="com.spring.aop.LogAop"></bean> </beans> |
5、Spring AOP注解详细介绍
l Spring AOP注解应用必须满足如下的事项
Ø 导入Aspectj的jar、Spring3.0-AOP.jar、aopalliance.jar即可
Ø 需要在配置文件中加入注解的配置,例如:bean-aop-annotiation.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: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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
如果使用Spring AOP注解,最好的用处就是减少在配置文件中的AOP内容。但是如果要掌握好Spring的AOP还需要学习注解的语法,下面的内容会给大家慢慢介绍 |
6、织入点语法
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;
@Aspect public class LogAop {
@Before("execution(public void com.spring.dao.impl.StudentDaoImpl.*(..))") public void logBefore() { System.out.println("方法执行之前转载日志"); } }
而execution(public void com.spring.dao.impl.StudentDaoImpl.*(..)),这个就是织入点的语法,它告诉AOP框架哪个类中方法需要进行AOP |
7、execution语法介绍
l execution(public * *(..))
l execution(* set*(..))
l execution(* com.xyz.service.AccountService.*(..))
l execution(* com.xyz.service..*.*(..))
l 语法格式:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) |
l 注意:上面的是Aspectj的语法,因为Spring的AOP中加入强大的Aspectj框架作为支撑
8、Spring AOP注解例子
l @Before前置建议,它是在执行一个业务方法之前插入的切面
l @AfterReturning,它是当一个方法正常运行后,执行的切面
l @After,它是当方法执行成功或者出现异常的时候都会执行切面
l @Around,它相当于一个AOP链,如果当前AOP执行后,就让下一个AOP执行
l @AfterThrowing,如果在方法中有错误抛出,则执行此建议
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;
@Aspect public class LogAop {
@Before("execution(public void com.spring.dao.impl.StudentDaoImpl.*(..))") public void logBefore() { System.out.println("方法执行之前转载日志"); }
@AfterReturning("execution(public void com.spring.dao.impl.StudentDaoImpl.insert(..))") public void logAfterReturning() { System.out.println("方法执行返回后载入日志"); }
@After("execution(public * com.spring.dao.impl.StudentDaoImpl.*(..))") public void logAfter() { System.out.println("Finally载入日志"); }
@Around("execution(public * com.spring.dao.impl.StudentDaoImpl.*(..))") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { System.out.println("===around建议载入日志===" + new Date()); Object o = pjp.proceed(); return o; }
@AfterThrowing("execution(public * com.spring.dao.impl.StudentDaoImpl.*(..))") public void logAfterThrowing() { System.out.println("===有参数异常载入日志===" + new Date()); } } |
9、Spring AOP基于XML文件配置介绍
l 一般情况下如果不想使用注解的方式来声明AOP,我们可以采用基于XML配置文件的方法来进行配置
l <aop:config.../>,此标签很重要。它是在XML里配置AOP功能的核心标签
Ø all aspect and advisor elements must be placed within an<aop:config> element
Ø An <aop:config> element can contain pointcut, advisor, andaspect elements
l 如果要使用<aop:config…/>一定要把AOP中一些俗语和概念搞懂【很重要】
10、下面给出如何基于XML配置AOP
l 创建LogAopXML的切面
package com.spring.aop;
import java.util.Date;
public class LogAopXML {
public void logBefore() { System.out.println("==基于XML的AOP前置建议==" + new Date()); } } |
l 创建bean-aop-xml.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: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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:config> <aop:aspect id="myAspect" ref="logAopXML"> <aop:pointcut expression="execution(* com.spring.dao.impl.TeacherDaoImpl.*(..))" id="businessService"/> <aop:before pointcut-ref="businessService" method="logBefore"></aop:before> </aop:aspect> </aop:config>
<bean id="teacherService" class="com.spring.services.TeacherService"> <property name="dao" ref="teacherDao"></property> </bean> <bean id="teacherDao" class="com.spring.dao.impl.TeacherDaoImpl"></bean> <bean id="logAopXML" class="com.spring.aop.LogAopXML"></bean> </beans>
上述代码中 <aop:config>,主要是配置存放切面,切入点,建议 <aop:aspect>,主要是配置切面类,一般需要制定好id,ref这两个属性 <aop:pointcut>,主要配置切入点,描述切入点规则 <aop:before>,主要配置的是前置建议 |
l 通过JUnit来进行单元测试
@Test public void testLogAopXml() { ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); TeacherService ts = (TeacherService)ac.getBean("teacherService"); ts.insert(); } |
11、Spring对Dao的支持
l Spring对JDBC的支持
l Spring对ORM框架的支持
l 重点先介绍Spring对JDBC支持。在Spring对JDBC支持中提供了一个模板JdbcTemplate,此模板封装了对JDBC操作的许多方法,且消除了忽视资源释放而引起的漏洞
l 后期Spring与MyBatis的整合我们在项目中告诉大家
l 需要导入的支持Spring对Jdbc封装包
Ø common-dbcp.jar: 提供数据源的第三方包
Ø common-pool.jar: common-dbcp.jar的依赖包
Ø spring-jdbc-4.0.3.jar:完成jdbc操作
Ø spring-tx-4.0.3.jar:jdbc事务异常相关类
Ø msyql-connector.jar:mysql的驱动包
12、我们来看一个应用Spring JDBC的程序编写步骤
l 配置数据源
l 数据源的配置Spring依赖于第三方两个数据源实现包:Apache-DBCP和C3P0。所以我们在配置数据源的时候可以任选其中一个
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/sampledb" p:username="root" p:password="1234" /> |
l 注意事项:BasicDataSource提供了close方法来关闭数据源,所以我们可以利用destory-method属性来执行关闭操作
l DBCP参数说明
Ø initialSize:初始化连接,即连接池启动时候创建的初始化连接数量。默认为0
Ø maxActive:最大活动连接,即连接池在同一时间能够分配的最大活动连接的数量,如果设置为负数则表示不限制。默认为8
Ø maxIdle:最大空闲连接,即连接池允许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制。默认为8
Ø minIdle:最小空闲连接,即连接池允许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建。默认为0
Ø maxWait:最大等待时间,即当没有可用连接时,连接池等待连接被归还的最大时间(单位:以毫秒计数),超过时间则抛异常。如果设置为-1表示无限制。默认为-1
l 结合属性文件进行数据源的配置
先创建jdbc.properites文件 jdbc.driverClassName=oracle.jdbc.driver.OracleDriver jdbc.url=jdbc:oracle:thin:@localhost:1521:XE jdbc.username=team3 jdbc.password=team3
在Spring的配置文件中可以编写如下的代码
<context:property-placeholder location="classpath:jdbc.properties">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> |
l JdbcTemplate模板应用
l 一般情况,我们在Dao类中使用JdbcTemplate,JdbcTemplate在XML配置文件配置好后,然后直接在Dao中注入
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"></bean> |
package com.gxaedu.dao;
import java.util.List; import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
@Repository //声明一个Dao public class UsersDao {
@Autowire //注入jdbcTemplate JdbcTemplate template;
public void query() { //用户的查询 String sql = "select * from users"; List<Map> list = template.queryForList(sql); System.out.println("list = " + list); }
public Map query(String username, String userpwd) { //获取用户信息的操作还是使用Spring的JDBC String sql = "select * from users where user_name = ? and user_pwd = ?"; Object[] obj = {username, userpwd}; return template.queryForMap(sql, obj); }
} |
l JdbcTemplate模板提供操作数据库的方法应用
例如: int rowCount = this.jdbcTemplate.queryForInt("select count(0) from t_accrual"); //返回一个int值
int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt( "select count(0) from t_actors where first_name = ?", new Object[]{"Joe"}); //通过参数的绑定来返回int值
String surname = (String) this.jdbcTemplate.queryForObject( "select surname from t_actor where id = ?", new Object[]{new Long(1212)}, String.class); //返回一个String类型
Actor actor = (Actor) this.jdbcTemplate.queryForObject( "select first_name, surname from t_actor where id = ?", new Object[]{new Long(1212)}, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setSurname(rs.getString("surname")); return actor; } }); //返回一个domain对象(JavaBean对象)
this.jdbcTemplate.update( "insert into t_actor (first_name, surname) values (?, ?)", new Object[] {"Leonor", "Watling"}); //插入操作
this.jdbcTemplate.update( "update t_actor set weapon = ? where id = ?", new Object[] {"Banjo", new Long(5276)}); //更新操作
this.jdbcTemplate.update( "delete from actor where id = ?", new Object[] {new Long.valueOf(actorId)}); //删除操作
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))"); //执行一个DDL语句 |
13、JdbcDaoSupport支持类应用
package com.spring.dao;
import java.util.List; import java.util.Map;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class SpringJdbcDao extends JdbcDaoSupport {
public void getTbUsers() { String sql = "select * from tb_user"; List<Map> list = getJdbcTemplate().queryForList(sql); for (Map m : list) { System.out.println(m.get("USER_ID")+"\t"+m.get("USER_NAME")); } } }
配置文件代码 <bean id="springjdbcdao" class="com.spring.dao.SpringJdbcDao"> <property name="dataSource" ref="dataSource"></property> </bean> |
14、批量SQL语句操作
@Repository public class JdbcActorDao {
@Autowried private JdbcTemplate jdbcTemplate;
public int[] batchUpdate(final List actors) { int[] updateCounts = jdbcTemplate.batchUpdate( "update t_actor set first_name = ?, last_name = ? where id = ?", new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setString(1, ((Actor)actors.get(i)).getFirstName()); ps.setString(2, ((Actor)actors.get(i)).getLastName()); ps.setLong(3, ((Actor)actors.get(i)).getId().longValue()); }
public int getBatchSize() { return actors.size(); } } ); return updateCounts; }
} |
15、Spring对Transaction的支持,这里只讲声明式事务管理配置
<?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" 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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 --> <context:component-scan base-package="com.gxaedu.dao"/> <context:component-scan base-package="com.gxaedu.service"/>
<!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/sampledb" p:username="root" p:password="1234" />
<!-- 配置Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" />
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" />
<!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 --> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceMethod" expression=" execution(* com.gxaedu.service..*(..))" /> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> </beans> |
测试你Spring事务是否成功
l 注意配置事务是接口代理,则测试程序是接口
l 交叉测试,一个Service里面有两个以上的Dao对象。让第一个Dao对象SQL语句能够执行成功,但是第二个Dao对象SQL语句操作失败,看事务能不能管理Service中的方法,让数据全部回滚