IOC基础使用
1、利用xml方式进行Bean管理
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
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:标识做用,不能含有特殊符号
name:遗留属性,几乎不用,与id相似,可使用'/'特殊符号
class:映射的class的全路径
scope:该Bean的做用范围
singleton:默认值,单表该Bean为一个单实例对象,即每次使用的都是同一个Bean,与Servlet同样
prototype:标识该Bean为一个多实例对象,与Action同样
request:spring建立一个Bean示例对象后存入request域对象中
session:spring建立一个Bean示例对象后存入session域对象中
globalSession:应用在Porlet环境中,若是没有Porlet环境,那么至关与Session
init-method:Bean示例初始化时执行该方法
destroy-method:Bean实例销毁时执行该方法,若是想执行该方法,必须是单实例对象,并且只有在ApplicationContext(工厂)关闭时才会执行
lazy-init:只对单例对象有用,是否延迟建立对象 默认值为default,即false,在加载配置文件时即建立实例对象
true:在加载配置文件时延迟建立实例对象,调用applicationContext.getBean()方法时建立实例对象
在beans标签中配置default-lazy-init="true",即将lazy-init的默认值设为对应的true or false ,控制全部的bean -->
<!-- 利用静态工厂建立Bean对象示例 -->
<bean id="beanFactory" factory-method="getCustomer"
class="cn.zz.spring.factory.BeanFactory"></bean>
<!-- 利用实例工厂建立Bean对象示例
1.先建立示例工厂对象
2.经过示例工厂中对应方法建立Bean示例对象
-->
<bean id="beanFactory2" class="cn.zz.spring.factory.BeanFactory2"></bean>
<bean id="customer" factory-bean="beanFactory2" factory-method="getCustomer"></bean>
<!-- 利用无参构造建立Bean实例对象 -->
<bean id="user" class="cn.zz.spring.domain.User" scope="singleton"
init-method="init" destroy-method="destroy" lazy-init="false">
<!-- 利用set方法注入String类型属性 -->
<property name="string" value="str"></property>
<!-- 利用set方法注入List集合类型属性 -->
<property name="list">
<list>
<value>123</value>
<value>456</value>
<value>789</value>
<value>123</value>
<value>456</value>
</list>
</property>
<!-- 利用set方法注入int类型属性 -->
<property name="i" value="1"></property>
<!-- 利用set方法注入double类型属性 -->
<property name="d" value="10.05"></property>
<!-- 利用set方法注入boolean类型属性 -->
<property name="b" value="1"></property>
<!-- 利用set方法注入数组类型属性 -->
<property name="arrs">
<array>
<value>111</value>
<value>222</value>
<value>333</value>
<value>444</value>
<!-- <ref bean="xxx"/> -->
</array>
</property>
<!-- 利用set方法注入Properties类型属性 -->
<property name="properties">
<props>
<prop key="name">123</prop>
<prop key="word">456</prop>
<prop key="age">789</prop>
</props>
</property>
<!-- 利用set方法注入Map集合类型属性 -->
<property name="map">
<map>
<entry key="a" value="123"></entry>
<entry key="b" value="456"></entry>
<entry key="c" value="789"></entry>
<!-- <entry key-ref="xxx" value-ref="xxx"></entry> -->
</map>
</property>
</bean>
<!-- 利用无参构造建立实例对象 -->
<bean name="people" class="cn.zz.spring.domain.People">
<!-- 利用set方法注入集合类型属性 -->
<property name="userlist">
<list>
<!-- 注入object类型集合数据 -->
<ref bean="user" />
<ref bean="user" />
<ref bean="user" />
</list>
</property>
</bean>
<!-- 利用无参构造建立实例对象 -->
<bean name="customer2" class="cn.zz.spring.domain.Customer">
<constructor-arg name="cname" value="李四"></constructor-arg>
<constructor-arg index="1" value="lalala"></constructor-arg>
<constructor-arg index="2" value="18"></constructor-arg>
<!-- <constructor-arg name="cpassword" value="lalala"></constructor-arg>
<constructor-arg name="age" value="18" type="int"></constructor-arg> -->
</bean>
<!--使用p名称空间进行属性注入
1.引入P名称空间:xmlns:p="http://www.springframework.org/schema/p"
2.使用P名称空间
*普通类型属性: p:属性名称="值"
*对象类型属性 p:属性名称-ref="beanId"
-->
<bean name="customerSupper" class="cn.zz.spring.domain.CustomerSupper" p:customer-ref="customer2" p:name="小黑"></bean>
<!-- 使用SpEL(Spring Expression Language)方式进行属性注入
SpEl是Spring3.x后的版本提供的方法
设置普通值:value="#{'String'}"
设置值对象中的的属性:value="#{BeanId.Attribute}"或者value="#{BeanId.methodName()}"
-->
<bean name="customerSupper2" class="cn.zz.spring.domain.CustomerSupper">
<property name="customer" ref="#{'customer2'}"></property>
<property name="name" value="#{customer2.getCname()}"></property>
</bean>
<!-- 引入另外一个applicattionContext文件,进行分模块管理classpath:表示类路径,可省略
在同一个applicationContext文件中,bean标签的id属性不可重复
在不一样的applicationContext文件中,bean标签的id属性可重复,后加载的会覆盖先加载的
-->
<import resource="classpath:applicationContext2.xml"/>
</beans>java
2、利用注解方式进行Bean管理
1.作Spring的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">
<!-- 开启注解扫描 ,对指定包中全部类的编译都会进行注解扫描-->
<context:component-scan base-package="cn.zz.spring"></context:component-scan>
<!-- 开启注解扫描,但只会扫描属性上的注解 -->
<!-- <context:annotation-config></context:annotation-config> -->
</beans>
2.利用注解方式建立对象
在须要被建立的对象的类上添加注解
设置该对象的一些属性
@Scope(value="prototype")设置该对象为多实例对象
3.利用注解注入属性
注入普通类型属性:在对应的属性上添加
@Value(value="xxx")注解,与xml中配置不一样,该方式不须要属性提供set方法;
注入对象类型属性:@Autowired和@Qualifier联合使用注入多态类型属性(spring框架中的注解)
@Autowired
@Quakifier(value="BeanId")
@Resource一个顶两(javax即java扩展功能中的注解,官方不建议使用)
@Resource(name="BeanId")
4.利用注解设置Bean实例的生命周期
在对应要设置的方式的方法中添加对应的注解
通常建议使用xml配置的无参构造方式建立对象,能够自行定义各类属性,注解有必定局限性
AOP学习基础
AOP概念
全称是Aspect-Oriented Programming,即面向切面的程序设计,底层使用动态代理实现
1、JDK代理,针对有接口的动态代理
public class TestDynamicProxy {
public static void main(String[] args) {
//1.得到一个已知实现类对象
ILook look = new LookImpl();
//2.利用proxy进行动态代理,获取代理类
ILook look2 = (ILook) Proxy.newProxyInstance(look.getClass().getClassLoader(), look.getClass().getInterfaces(),new ProxyClass(look));
look2.look();
}
}
/**
* InvocationHandler 是代理实例的调用处理程序 实现的接口
* 即建立一个代理实例
* @author ZZ
*
*/
class ProxyClass implements InvocationHandler{
//设置一个成员变量用来接收被代理类的对象,look即被代理对象
ILook look;
public ProxyClass(ILook look){
this.look = look;
}
/**
* proxy:表示当前这个代理类对象
* method:表示当前方法
* args:表示方法参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//加强指定的方法
if("look".equals(method.getName())){
System.out.println("加强look...");
return null;
}
//放心其它的方法
return method.invoke(look, args);
}
}
2、Cglib代理,针对没有接口的动态代理
public class TestCglibDynamicProxy {
public static void main(String[] args) {
//1.得到被代理的对象
See see = new SeeChild();
//建立一个Cglib动态代理类
ProxyClassCglib pr = new ProxyClassCglib(see);
//得到代理对象
See creatSee = pr.creatSee();
creatSee.see();
}
}
class ProxyClassCglib implements MethodInterceptor{
//1.建立一个用来接收代理类对象的成员变量
private See see;
//2.设置构造
public ProxyClassCglib(See see){
this.see = see;
}
/**
* 加强指定方法
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("see".equals(method.getName())){
/**
* methodProxy.invokeSuper(proxy, args);
* 执行当前代理类的父类中的see的对应方法
* method.invoke(see, args);
* 执行被代理类的对应方法
*/
method.invoke(see, args);
methodProxy.invokeSuper(proxy, args);
System.out.println("加强see");
return null;
}
return method.invoke(see, args);
}
//4.返回代理对象
public See creatSee(){
//1.建立Cglib核心文件
Enhancer enhancer = new Enhancer();
//2.设置父类(设置父类的话,若是设置为父类.class,能够在加强方法中便可调用当前类的方法,也能够调用代理类对应的方法;若是设置代理对象.class,则只能够在加强方法中执行代理对象中对应的方法)
enhancer.setSuperclass(See.class);
//3.设置回调Callback类型,Callback应该是个MethodInterceptor的父接口,没有源码、、
enhancer.setCallback(this);
//4.生成代理类
See see = (See) enhancer.create();
//返回代理对象
return see;
}
}
Spring基于AspectJ的AOP开发
1、操做术语
2、xml方式操做AspectJ进行AOP开发
AspectJ表达式
基本样式:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
经常使用表达式
1.得到指定方法
execution(* cn.zz.xxx.method(..))
* 表示访问修饰符和返回值类型是任意的,method(..)表示指定的方法名,参数任意
2.同理能够设置全部方法名,全部包各类。。。
execution(* *.*(..))即全部包中的全部方法
execution(* cn.zz.*.*(..)) 即zz包下的全部方法
3.execution(*.xxx*(..))方法名称是save开头作加强
4.execution(* cn.zz..*(..)zz包和其全部子包,孙包中的全部方法
5.excution(* cn.zz.xxx.Ixxx+.*(..)) 当前包下指定接口的全部实现类中的全部方法(-:暂时未知)
3.通知类型
<bean id="customer2" class="cn.zz.spring.domain.Customer2"></bean>
<bean id="user2" class="cn.zz.spring.domain.User2"></bean>
<aop:config>
<aop:pointcut expression="execution(* cn.zz.spring.domain.User2.run(..))" id="p1"/>
<aop:aspect ref="customer2">
<aop:before method="run" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>
<aop:before>:前置通知
<aop:aroubd>:环绕通知
<aop:after-returning>:后置通知
<aop:after-throw>:异常通知
<aop:after>:最终通知
3、注解方式操做AspectJ进行AOP开发
<!-- 配置开启AOP中的注解扫描 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
在加强方法的类上添加注解@Aspect
在对应方法上添加@Before,@After等等。。配置value="execution()"AspectJ表达式
4、Spring整合Junit

引入Spring-test.jar包
在须要被建立的对象中设置两个注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
JdbcTemplate模板操做
配置信息
<!-- 得到外部引入的方式的链接池配置参数 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:c3p0.properties"></property>
</bean>
<!-- 得到外部文件的参数第二种方式
<context:property-placeholder location="classpath:c3p0.properties"/>
-->
<!-- 配置链接池IOC -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driver}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 配置JdbcTemplate -->
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
测试代码
/**
* 利用spring自带的链接池得到单个数据
*/
@Test
public void testDemo1(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test_spring");
dataSource.setUsername("root");
dataSource.setPassword("root");
JdbcTemplate template = new JdbcTemplate(dataSource);
String sql = "select count(*) from customer";
Integer i = template.queryForObject(sql, Integer.class);
System.out.println(i);
}
/**
* 利用C3P0链接池得到单个对象
*/
@Test
public void testDemo2(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test_spring");
dataSource.setUser("root");
dataSource.setPassword("root");
JdbcTemplate template = new JdbcTemplate(dataSource);
String sql = "select * from customer where cname=?";
Customer customer = template.queryForObject(sql, new RowMapper<Customer>(){
@Override
public Customer mapRow(ResultSet set, int rows) throws SQLException {
Customer customer = new Customer();
String cname = set.getString("cname");
String address = set.getString("address");
customer.setCname(cname);
customer.setAddress(address);
return customer;
}
}, "网易");
System.out.println(customer.getAddress());
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
/**
* 利用IOC方式得到各个对象来得到对象集合
*/
@SuppressWarnings("resource")
@Test
public void testDemo3(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate template = (JdbcTemplate) context.getBean("template");
String sql = "select * from customer";
List<Customer> list = template.query(sql, new RowMapper<Customer>(){
@Override
public Customer mapRow(ResultSet set, int rows) throws SQLException {
String cname = set.getString("cname");
String address = set.getString("address");
Customer customer = new Customer();
customer.setCname(cname);
customer.setAddress(address);
return customer;
}
});
System.out.println(list);
}
Spting事物操做
事物的传播行为
指在一个事物中调用另一个事物



利用配置文件控制事物和
事物的传播行为
事物管理API:PlatformTransactionManager(事物管理器)
<!-- 配置JdbcTemplate -->
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置Spring的JdbcTemplate模板的事物控制 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事物加强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- method:指定要执行事物的方法名称
propagation:指定事物传播行为方式
isolation:指定事物的隔离级别
-->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut expression="execution(* cn.zz.spring.service.*.*(..))" id="p1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="p1"/>
</aop:config>
利用注解控制事物和事物的传播行为
<!-- 开启IOC注解扫描 :只会扫描属性上的注解-->
<context:annotation-config></context:annotation-config>
<!-- 开启AOP注解扫描 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 开启事物注解扫描 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置transactionManager的 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置C3P0的DataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driver}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 加载配置c3p0参数的Properties文件 -->
<!-- <context:property-placeholder location="classpath:c3p0.properties"/> -->
<!-- 得到外部引入的方式的链接池配置参数 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:c3p0.properties"></property>
</bean>
<!-- 配置各类Bean信息 -->
<bean id="userService2" class="cn.zz.spring.service2.UserService2"></bean>
<bean id="userDao" class="cn.zz.spring.dao.UserDao"></bean>
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
在须要进行事物控制的类或者方法上添加注解
@Transactional