六大模块
核心容器模块
spring中最核心的模块。负责Bean的创建,配置和管理。主要包括:beans,core,context,expression等模块。
Spring的AOP模块
主要负责对面向切面编程的支持,帮助应用对象解耦。
数据访问和集成模块
包括JDBC,ORM,OXM,JMS和事务处理模块,其细节如下:
JDBC模块提供了不再需要冗长的JDBC编码相关了JDBC的抽象层。
ORM模块提供的集成层。流行的对象关系映射API,包括JPA,JDO,Hibernate和iBatis。
OXM模块提供了一个支持对象/ XML映射实现对JAXB,Castor,使用XMLBeans,JiBX和XStream 的抽象层。
Java消息服务JMS模块包含的功能为生产和消费的信息。
事务模块支持编程和声明式事务管理实现特殊接口类,并为所有的POJO。
Web和远程调用
包括web,servlet,struts,portlet模块。
测试模块
工具模块
IOC-控制反转
Spring的特性之一:IOC(控制反转Inverse Of Control),又称依赖注入,是一种重要的面向对象编程的法则来削减计算机程序的耦合问题也是轻量级spring框架的核心;
注入方法
1.属性注入
beans.xml配置实例:
<bean id="people2" class="com.java1234.entity.People">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
<property name="age"
value="11"></property>
</bean>
2.构造器注入:(通过类型;索引;联合使用)
类型配置实例:
<bean id="people3"
class="com.java1234.entity.People">
<constructor-arg type="int"
value="2"></constructor-arg>
<constructor-arg
type="String" value="李四"></constructor-arg>
<constructor-arg
type="int" value="22"></constructor-arg>-------构造器注入对应的People类必须有带这3个参数的构造器(此时可以没有get/set方法)
</bean>
索引配置实例:
<bean id="people4"
class="com.java1234.entity.People">
<constructor-arg index="0"
value="3"></constructor-arg>
<constructor-arg index="1" value="王五"></constructor-arg>
<constructor-arg index="2"
value="55"></constructor-arg>
</bean>
联合使用
<bean id="people5"
class="com.java1234.entity.People">
<constructor-arg index="0" type="int"
value="4"></constructor-arg>
<constructor-arg index="1" type="String"
value="招六"></constructor-arg>
<constructor-arg index="2" type="int"
value="66"></constructor-arg>
</bean>
3.工厂注入(非静态工厂;静态工厂)
非静态工厂:
<bean id="peopleFactory"
class="com.java1234.factory.PeopleFactory"></bean>
<bean id="people7"
factory-bean="peopleFactory"
factory-method="createPeople"></bean>
静态工厂:
<bean id="people8" class="com.java1234.factory.PeopleFactory2" factory-method="createPeople"></bean>
《静态工厂不用创建对象,所以可以一步完成》
4.泛型依赖注入(整合Hibernate的时候讲)
注入参数
1.属性注入
2.bean注入(<property name="dog" ref="...."></property>)
3.内部bean注入
4.null值
5.级联属性
6.集合类型属性
1.内部bean注入
<bean
id="people3" class="com.java1234.entity.People">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
<property name="age"
value="11"></property>
<property name="dog">
<bean class="com.java1234.entity.Dog">
<property name="name"
value="Tom"></property>
</bean>
</property>
</bean>
2.注入null
<bean
id="people4" class="com.java1234.entity.People">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="11"></property>
<property name="dog">
<null></null>
</property>
</bean>
3. 注入集合类型list,set,map
<bean
id="people6" class="com.java1234.entity.People">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
<property name="age"
value="11"></property>
<property name="dog"
ref="dog1"></property>
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
</list>
</property>
<property name="loves">
<set>
<value>唱歌2</value>
<value>跳舞2</value>
</set>
</property>
<property name="works">
<map>
<entry>
<key><value>上午</value></key>
<value>写代码</value>
</entry>
<entry>
<key><value>下午</value></key>
<value>测试代码</value>
</entry>
</map>
</property>
<property name="addresses">
<props>
<prop key="address1">aaaaa</prop>
<prop key="address2">bbbbb</prop>
</props>
</property>
</bean>
5.Spring的自动装配
通过default-autowire属性来进行装配,其类型有byName, byType, constructor
例如在beans.xml配置:default-autowire="constructor">
bean id="dog2"
class="com.java1234.entity.Dog">
<property name="name"
value="Jack"></property>
</bean>
<bean id="people1"
class="com.java1234.entity.People">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
<property name="age"
value="11"></property>
</bean>
在People类里面就会调用下面的构造器:
public People(Dog dog) {
super();
System.out.println("constructor11");
this.dog = dog;
}
---自动装配要慎用,其屏蔽了装配细节,容易产生潜在的错误;
Spring bean作用域默认是 单例singleton 可以通过配置scope="prototype",实现多例
bean之间的关系:
6.继承;依赖;引用
继承:配置实例如下:
<bean id="abstractPeople"
class="com.java1234.entity.People" abstract="true">
<property name="className" value="高三5班"></property>
<property name="age"
value="19"></property>
</bean>
<bean id="zhangsan" parent="abstractPeople"
depends-on="autority">
<property name="id"
value="1"></property>
<property name="name" value="张三"></property>
</bean>
---继承会有重写;
depends-on="autority">体现了依赖,如果不加autority这个bean的实例化按照beans.xml中的顺序
AOP-面向切面编程
before
方法被调用之前调用
after
方法完成后调用通知,无论方法执行是否成功
After-returning
在方法 成功执行 之后调用通知
After-throwing
方法抛出异常后调用通知
Around
通知包裹了被通知的方法,在被通知的方法调用之前或之后执行自定义的行为
DAO-持久层支持
数据源配置
DBCP
Spring对jdbc的支持:beans.xml配置文件的部分代码
<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>
/*
C3P0
也可以通过如下C3P0数据源实现
<bean
id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="
oracle.jdbc.driver.OracleDriver
"/>
<property name="jdbcUrl" value="
jdbc:oracle:thin:@localhost:1521:ora9i
"/>
<property name="user"
value="admin"/>
<property name="password"
value="1234"/>
bean>
*/
属性文件properties
<context:property-placeholder location="jdbc.properties"/>//通过这个属性就可以在properties文件中取找
/*也可以通过如下写法
<bean
id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"
value="/WEB-INF/jdbc.properties"/>
bean>
*/
JdbcTemplate
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource"
ref="dataSource"></property>//将数据源注入到jdbcTemplate类
</bean>
<bean id="studentDao"
class="com.java1234.dao.impl.StudentDaoImpl">
<property name="jdbcTemplate"
ref="jdbcTemplate"></property>//将jdbc注入到业务层,这样就可以通过实现类的方法进行对表的操作
</bean>
上面使用的是jdbcTemplate
还可以通过:JdbcDaoSupport(此时beans.xml中直接将数据源注入到实现类,实现类继承 JdbcDaoSupport<public class StudentDaoImpl extends JdbcDaoSupport implements StudentDao>)
增加的写法:
public int
addStudent(Student student) {
String sql="insert into t_student values(null,?,?)";
Object []params=new Object[]{student.getName(),student.getAge()};
return this.getJdbcTemplate().update(sql,params);
}
NamedParameterJdbcTemplate
增加的写法:
@Override
public int addStudent(Student student) {
String sql="insert into t_student
values(null,:name,:age)";
MapSqlParameterSource sps=new MapSqlParameterSource();
sps.addValue("name", student.getName());
sps.addValue("age", student.getAge());
return namedParameterJdbcTemplate.update(sql,sps);
}
--将数据源注入这3个类,再将这个类注入到业务层,都可以实现增删改查
Transaction事务处理
beans.xml文件的配置:
<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>
<!-- jdbc事务管理器 -->
<bean
id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property
name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property
name="transactionManager"
ref="transactionManager"></property>
</bean>//将这个template对象注入到业务类
<context:property-placeholder location="jdbc.properties"/>
<bean id="namedParameterJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg
ref="dataSource"></constructor-arg>
</bean>
<bean id="bankDao" class="com.java1234.dao.impl.BankDaoImpl">
<property name="namedParameterJdbcTemplate"
ref="namedParameterJdbcTemplate"></property>
</bean>
<bean id="bankService"
class="com.java1234.service.impl.BankServiceImpl">
<property name="bankDao"
ref="bankDao"></property>
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
在业务类中就可以按照如下操作:
@Override
public void transferAccounts(final int count, final int userIdA, final
int userIdB) {
// TODO Auto-generated method stub
transactionTemplate.execute(new
TransactionCallbackWithoutResult() {
@Override
protected void
doInTransactionWithoutResult(TransactionStatus arg0) {
// TODO Auto-generated
method stub
bankDao.outMoney(count,
userIdA);
bankDao.inMoney(count,
userIdB);
}
});
} //这里就是通过一个匿名内部类,没有就过就回滚
上面描述的编程式事物管理;另外还有声明式事物管理(有分为使用xml配置声明事务,使用注解声明事务)
xml配置事务管理
<!-- jdbc事务管理器 -->
<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>
<tx:method name="insert*" propagation="REQUIRED"
/>
<tx:method name="update*" propagation="REQUIRED"
/>
<tx:method name="edit*" propagation="REQUIRED"
/>
<tx:method name="save*" propagation="REQUIRED"
/>
<tx:method name="add*" propagation="REQUIRED"
/>
<tx:method name="new*" propagation="REQUIRED"
/>
<tx:method name="set*" propagation="REQUIRED"
/>
<tx:method name="remove*" propagation="REQUIRED"
/>
<tx:method name="delete*" propagation="REQUIRED"
/>
<tx:method name="change*" propagation="REQUIRED"
/>
<tx:method name="get*" propagation="REQUIRED"
read-only="true" />
<tx:method name="find*" propagation="REQUIRED"
read-only="true" />
<tx:method name="load*" propagation="REQUIRED"
read-only="true" />
<tx:method name="*" propagation="REQUIRED"
read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置事务切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut id="serviceMethod"
expression="execution(* com.java1234.service.*.*(..))" />
<!-- 配置事务通知 -->
<aop:advisor advice-ref="txAdvice"
pointcut-ref="serviceMethod"/>
</aop:config>
注解配置事务管理
<!-- jdbc事务管理器 -->
<bean id="transactionManager"
spring--doc文档连接http://spring.cndocs.tk/
http://wenku.baidu.com/link?url=pOTfRLWGk91H0ydqHbSymWlRU86G6WgvZqrtilWq06kwAfkEU9yG4KvvYuiKfDgYi6uaVQoUtUK26ON-H-gvin8DAnb45qrF1nhqUGxnxzy
连接数据库:jdbc.properties
1、Oracle
<context:property-placeholder location="jdbc.properties"/>
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@132.224.24.118:1521:jsfx
jdbc.username=sett_analyse
jdbc.password=g4el_yj_ha
2、MySql
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_spring
jdbc.username=root
jdbc.password=123456
引入多个配置文件
对于一个大型的web应用来说,可能 有多个xml配置文件,在启动spring容器时,可以通过一个string数组指定这些配置文件,spring还允许我们通过<import>将多个配置文件引入到一个文件中,进行配置文件的集成,这样在启动spring容器时,只需要指定这个合并好的文件即可,如果在spring容器启动时2个配置,文件都在配置文件列表中,那么这2个配置文件的bean就可以互相引用。
注解Annotation
定义一个Dao的bean,我们可以通过使用注解:Component("userDao")可以被spring容器识别,spring容器自动将pojo转换成容器管理的bean
除了Component以外,spring还提供了3个功能基本和它等效的注解:
他们分别对Dao Service Controller进行注解:
@Repository
@Service
@Controller
---只所以要增加这3个注解,是为了让标注类的用途更清晰,但你完全可以用Component代替者3个注解;
添加扫描:
<context:component-scan base-package="">
@Autowired
使用Autowired注解实现bean的依赖注入,此注解默认按照类型匹配的方式,在容器中查找匹配的bean,找不到抛异常,
使用@Qualifier指定注入bean的名称,如果容器有一个以上匹配的bean时,则可以通过这个注解指定
例如容器中有两个UserDao类型的bean,一个名为userDao 另一个是otherUserDao
对类方法进行注解:
@Autowired可以对变量已经方法的入参进行标注;如果入参有多个,自动选择匹配入参类型的bean,spring允许对方法入参标注
@Qualifier以指定注入bean的名称:
@Autowired
public void init(@Qualifier("userDao") UserDao userDao,LogDao logDao){
}
--一般情况下:在Spring容器中大部分的bean都是单实例的,所以一般无须通过@Repository@Service的value属性为bean指定名称
也无须使用@Qualifier按名称进行注入;
对集合类进行标注:
如果对类中集合类的变量或方法进行Autowired标注,spring会将容器中类型匹配的所有bean都自动注入进来,
对标准注解的支持:
Spring还支持JSR-250中定义的 注解Resource和JSR-330中定义的@Inject注解;这2种注解和@Autowired注解类似;
都是对类变量和方法入参提供自动注入的功能,
@Resource("car")
private void setCar(Car car){
}
这时如果注解@Resource未指定bean的名称,则可以通过属性的方法得到需要注入的bean名称;
可见 @Autowired默认是按照类型匹配注入bean @Resource按照名称注入bean
而@Inject和@Autowired一样也是通过类型注入bean 只是没有require属性;
因此不管是@Resource还是@Inject其功能都是没有@Autowired丰富,因此除非必要,大可不必在乎这2个注解
@PostConstruct和@PreDestory
通过注解@PostConstruct和@PreDestory注解,在spring中他们相当于init-method和destory-method属性的功能;不过使用注解时可以在一个bean中定义多个;
@Configuration
普通的POJO只要标注@Configuration注解,就可以为spring容器提供Bean定义的 信息了;
每个标注@Bean的类方法都相当于提供一个bean的定义信息
使用基于java类的配置信息启动spring容器
直接通过@Configuration注解的类启动spring容器:
spring提供了一个AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的类启动spring容器:
//ApplicationContext
ac=new ClassPathXmlApplicationContext("beans.xml");
ApplicationContext ac = new
AnnotationConfigApplicationContext(HelloWorld.class);//HelloWorld类用Configuration注解
HelloWorld
helloWorld=(HelloWorld)ac.getBean("helloWorld");//getBean的参数也可以写成HelloWorld.class
此外 AnnotationConfigApplicationContext还支持通过编码的方式加载多个Configuration类
ct.register(HelloWorld.class);