十四、Spring中hibernateTemplate的使用
最后更新于:2022-04-01 11:38:35
HibernateTemplate的配置和使用:
1、配置bean文件:因为要用到sessionFactory索性就都复制了过来.也方便大家看
~~~
<?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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config />
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 将前面类写入容器 -->
<bean id="logInterceptor" class="com.spring.aop.LogInterceptor" />
<!--
配置数据源 <bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName"
value="com.mysql.jdbc.Driver"/> <property name="url"
value="jdbc:mysql://localhost:3306/sms"/> <property name="username"
value="root"/> <property name="password" value="root"/> </bean>
-->
<!-- placeholder 占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- 配置dataSource -->
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<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>
<!-- 将配置好的dataSource注入到SessionFactory中-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/spring/model/user.hbm.xml</value>
<value>com/spring/model/userlog.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
</value>
</property>
</bean>
<!-- 声明式事务管理,事务需要数据源,从sessionFactory中拿到
这是一个AOP的应用 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务要管理的方法 -->
<tx:advice transaction-manager="transactionManager" id="txManager">
<tx:attributes>
<tx:method name="save"/>
</tx:attributes>
</tx:advice>
<!-- 配置aop设置切面和织入点逻辑 -->
<aop:config>
<aop:pointcut id="entryPointMethod" expression="execution(public * com.spring.service..*.*(..))"/>
<aop:advisor
advice-ref="txManager"
pointcut-ref="entryPointMethod"
/>
</aop:config>
<!-- 配置一个hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
~~~
2、使用@resource注入,然后调用save方法:
~~~
@Component("userDaoImpl")
public class UserDaoImpl implements UserDao{
@Resource
private HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
@Override
public void save(User u) {
try {
hibernateTemplate.save(u);
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
~~~
十三、Spring中Xml声明事务
最后更新于:2022-04-01 11:38:33
补充知识点:
事务的传播特性:在当前的执行环境中。如果有多个方法嵌套互相调用的话,那么事务的特性必将从第一个方法传播到第二个、第三个。。。。
~~~
/*事务的传播性。如果当前执行环境中有事务,那么则会一直在
* 传播环境中传播下去。如果没有事务那么则会创建一个事务
* 默认就是required
* 而readOnly属性则是规定该事务只能是一些select操作。而insert,update等
* 动作是不能执行的。因为readonly的限制,而且拿到readonly=true的transation
* 的话它的执行效率是比前者高的
* 还有更多事务配置请在:
*http://static.springsource.org/spring/docs/2.5.6/reference/transaction.html#transaction-strategies
* 9.5.6.1. @Transactionalsettings 中查看
*/
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)
public void save(User u){
u.setName("zhanglong");
UserLog log = new UserLog();
log.setMsg("useradded");
userDaoImpl.save(u);
userLogDaoImpl.save(log);
}
~~~
下面看一个xml配置事务的案例:
1、 编写业务逻辑操作的简单方法:
~~~
@Component("userService")
public class UserServiceImpl implements UserService{
@Resource
private UserDao userDaoImpl;
@Resource
private UserLogDao userLogDaoImpl;
public UserLogDao getUserLogDaoImpl() {
return userLogDaoImpl;
}
public void setUserLogDaoImpl(UserLogDao userLogDaoImpl) {
this.userLogDaoImpl = userLogDaoImpl;
}
public UserDao getUserDaoImpl() {
return userDaoImpl;
}
public void setUserDaoImpl(UserDao userDaoImpl) {
this.userDaoImpl = userDaoImpl;
}
public void save(User u){
u.setName("zhanglong");
UserLog log = new UserLog();
log.setMsg("user added");
userDaoImpl.save(u);
userLogDaoImpl.save(log);
}
}
~~~
2、 编写XML配置文件,将事务加上去:
下面的文件主要包括配置数据库和指定事务前一段不用看。我们主要看事务在xml中的配置
1、 配置事务管理器transactionManager
2、 配置事务要管理的方法tx:advice
3、 配置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: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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config />
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 将前面类写入容器 -->
<bean id="logInterceptor" class="com.spring.aop.LogInterceptor" />
<!--
配置数据源 <bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName"
value="com.mysql.jdbc.Driver"/> <property name="url"
value="jdbc:mysql://localhost:3306/sms"/> <property name="username"
value="root"/> <property name="password" value="root"/> </bean>
-->
<!-- placeholder 占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- 配置dataSource -->
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<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>
<!-- 将配置好的dataSource注入到SessionFactory中-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/spring/model/user.hbm.xml</value>
<value>com/spring/model/userlog.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
</value>
</property>
</bean>
<!-- ---------------------------以上是数据源和sessionFactory的配置 ----------------------------- -->
<!-- 声明式事务管理,事务需要数据源,从sessionFactory中拿到
这是一个AOP的应用 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务要管理的方法 -->
<tx:advice transaction-manager="transactionManager" id="txManager">
<tx:attributes>
<tx:method name="save" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置aop设置切面和织入点逻辑 -->
<aop:config>
<aop:pointcut id="entryPointMethod" expression="execution(public * com.spring.service..*.*(..))"/>
<aop:advisor
advice-ref="txManager"
pointcut-ref="entryPointMethod"
/>
</aop:config>
</beans>
~~~
### 文档参考Spring官方文档的:9.5.8. Advisingtransactional operations
[http://static.springsource.org/spring/docs/2.5.6/reference/transaction.html#transaction-declarative-applying-more-than-just-tx-advice](http://static.springsource.org/spring/docs/2.5.6/reference/transaction.html#transaction-declarative-applying-more-than-just-tx-advice)
十二、Spring中Annotation声明事务
最后更新于:2022-04-01 11:38:31
Spring的声明式事务Annotation的实现------AOP应用
首先先讨论一个问题:
**事务放在service层还是放在dao层呢?**
Dao层只是针对于某一个实体进行CRUD的操作。如果在增加删除一个表的时候。比如USER我们要在LOG表中记录相应的日志。那么在DAO层如何完成。所以说Service层可能操作多个实体类。所以事务加载service层比较合适。因为不论我们保存哪一个实例出现了错误我们都可以回滚。而不是Log插入了,User没插入。反之亦然,这都是我们不愿意看到的。
下面举例Spring中事务通过Annotation方式是如何实现的:
**1、 加入tx开头的命名空间并且配置事务manager和driven。代码如下:**
~~~
<?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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config />
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 将前面类写入容器 -->
<bean id="logInterceptor" class="com.spring.aop.LogInterceptor" />
<!--
配置数据源 <bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName"
value="com.mysql.jdbc.Driver"/> <property name="url"
value="jdbc:mysql://localhost:3306/sms"/> <property name="username"
value="root"/> <property name="password" value="root"/> </bean>
-->
<!-- placeholder 占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- 配置dataSource -->
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<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>
<!-- 将配置好的dataSource注入到SessionFactory中-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/spring/model/user.hbm.xml</value>
<value>com/spring/model/userlog.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
</value>
</property>
</bean>
<!-- 声明式事务管理,事务需要数据源,从sessionFactory中拿到
这是一个AOP的应用 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 声明式事务注解的配置 -->
<tx:annotation-driven />
</beans>
~~~
**2、在Java文件上使用注解标签:**
~~~
//在Service层加入事务的控制。具体逻辑不在给予。
//在下面方法前面加逻辑
/*事务的传播性。如果当前执行环境中有事务,那么则会一直在
* 传播环境中传播下去。如果没有事务那么则会创建一个事务
*/
@Transactional(propagation=Propagation.REQUIRED)
public void save(User u){
u.setName("zhanglong");
UserLog log = new UserLog();
log.setMsg("user added");
userDaoImpl.save(u);
userLogDaoImpl.save(log);
}
~~~
十一、Spring整合Hibernte
最后更新于:2022-04-01 11:38:29
**小知识插曲:**
在MyEclipse中如何将源码配置到相关的jar包:
Jar包---propreties------JavaSourceAttachment------External File ----fileof source.jar
**1、 编写jdbc.properties配置jdbc的相关参数**
~~~
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sms
jdbc.username=root
jdbc.password=root
~~~
**2、编写Javabean和映射文件:**
~~~
JavaBean:
package com.spring.model;
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
~~~
**映射文件:**
~~~
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="com.spring.model">
<class name="User">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
</class>
</hibernate-mapping>
~~~
**3、 配置spring容器初始化sessionFactory**
~~~
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config />
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 将前面类写入容器 -->
<bean id="logInterceptor" class="com.spring.aop.LogInterceptor" />
<!--
配置数据源 <bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName"
value="com.mysql.jdbc.Driver"/> <property name="url"
value="jdbc:mysql://localhost:3306/sms"/> <property name="username"
value="root"/> <property name="password" value="root"/> </bean>
-->
<!-- placeholder 占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- 配置dataSource -->
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<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>
<!-- 将配置好的dataSource注入到SessionFactory中-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/spring/model/user.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
</value>
</property>
</bean>
</beans>
~~~
**4、编写测试类:**
~~~
package com.spring.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.UserService;
public class SpringTest {
@Test
public void test01() {
BeanFactory applicationContext = new ClassPathXmlApplicationContext(
"beans.xml");
UserService user = (UserService) applicationContext.getBean("userService");
user.save();
}
}
~~~
**需要的hibernate Jar包:**
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-04_5729a8ff66930.jpg)
**需要的spring jar包:**
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-04_5729a8ff85a3b.jpg)
此外还需要Junit、数据库连接驱动、J2ee的jar包
十、Spring DBCP用xml和properties2种格式配置DataSource
最后更新于:2022-04-01 11:38:26
Spring提供数据库连接池:DBCP配置DataSource并且获取连接完成数据库操作:
Spring帮助文档的地址:
[http://static.springsource.org/spring/docs/2.5.6/reference/beans.html#beans-value-element](http://static.springsource.org/spring/docs/2.5.6/reference/beans.html#beans-value-element)
以下内容需要导入的jar包:
commons-dbcp.jar
commons-pool.jar
mysql-connector-java-5.0-nightly-20071116-bin.jar
**1. 首先在容器内配置数据源**
~~~
<!-- 配置数据源 -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/sms"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
~~~
**2.拿到注入数据源并且编写对数据库的操作**
~~~
@Component("userService")
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Resource //resource注入
private DataSource myDataSource;
public DataSource getMyDataSource() {
return myDataSource;
}
public void setMyDataSource(DataSource myDataSource) {
this.myDataSource = myDataSource;
}
//在下面方法前面加逻辑
public void save(){
try{
//拿到连接执行操作
Connection conn = myDataSource.getConnection();
conn.createStatement().execute("insert into dept values('6','bumen2')");
}catch(Exception e){
e.printStackTrace();
}
}
}
~~~
**3.测试运行**
~~~
@Test
public void test01() {
BeanFactory applicationContext = new ClassPathXmlApplicationContext(
"beans.xml");
UserService user = (UserService) applicationContext.getBean("userService");
user.save();
}
~~~
**-通过Properties的方式配置xml的datasource:**
**1、 编写properties文件:**
~~~
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sms
jdbc.username=root
jdbc.password=root
~~~
**2、编写xml容器配置:**
~~~
<!-- placeholder 占位符 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<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>
~~~
九、Spring Aop 用xml的方式实现
最后更新于:2022-04-01 11:38:24
学习完了Spring AOPAnnotation之后在再学xml方式的我觉得就很简明易懂了。这个案例不再将一些细节性的问题再次叙述,请看案例代码,如下所示:
1、 编写被代理对象:
~~~
import org.springframework.stereotype.Component;
import com.spring.dao.UserDao;
@Component("userService")
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//在下面方法前面加逻辑
public void HelloWorld(){
System.out.println("helloworld");
}
}
~~~
2、编写配置文件:
~~~
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" >
<context:annotation-config/>
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 将前面类写入容器 -->
<bean id="logInterceptor" class="com.spring.aop.LogInterceptor" />
<!-- 配置AOP -->
<aop:config>
<!-- 声明pointcut -->
<aop:pointcut expression="execution(public * com.spring.service..*.*(..))" id="servicepoint" />
<!-- 声明切面类 -->
<aop:aspect id="aspectLog" ref="logInterceptor">
<aop:before method="BeforeMethod" pointcut-ref="servicepoint"/>
<aop:after-returning method="AfterMethod" pointcut-ref="servicepoint"/>
<aop:around method="aroundProcced" pointcut-ref="servicepoint"/>
</aop:aspect>
</aop:config>
</beans>
~~~
3、编写测试文件:
~~~
package com.spring.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.UserService;
public class SpringTest {
@Test
public void test01() {
BeanFactory applicationContext = new ClassPathXmlApplicationContext(
"beans.xml");
UserService user = (UserService) applicationContext.getBean("userService");
user.HelloWorld();
}
}
~~~
八、Spring Aop织入点语法和相关案例总结
最后更新于:2022-04-01 11:38:22
**Aspectj织入点语法:**
1、execution(public * *(..)) 任何类的任何返回值的任何方法
2、execution(* set*(..)) 任何类的set开头的方法
3、execution(* com.xyz.service.AccountService.*(..)) 任何返回值的规定类里面的方法
4、execution(* com.xyz.service..*.*(..)) 任何返回值的,规定包或者规定包子包的任何类任何方法
**Advise总结。举例说明:**
1、举例:直接指定要织入的位置和逻辑
~~~
//指定织入的方法。
@Before("execution(public * com.spring.service..*.*(..))")
public void BeforeMethod(){
System.out.println("method start!");
}
@AfterReturning("execution(public * com.spring.service..*.*(..))")
public void AfterMethod(){
System.out.println("After returnning");
}
~~~
2、通过定义pointcut来指定:
~~~
//定义pointcut织入点集合
@Pointcut("execution(public * com.spring.service..*.*(..))")
public void MyMethod(){}
@Before("MyMethod()")
public void BeforeMethod(){
System.out.println("method start!");
}
@AfterReturning("MyMethod()")
public void AfterMethod(){
System.out.println("After returnning");
}
//执行前后都拦截。以pjp.proceed的方法分割开来
@Around("MyMethod()")
public void aroundProcced(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("around start");
pjp.proceed();
System.out.println("around end");
}
~~~
输出结果:
method start!
around start
helloworld
After returnning
around end
七、Spring Aop的理解和简单实现
最后更新于:2022-04-01 11:38:20
**1、AOP概念**
所说的面向切面编程其实就是在处理一系列业务逻辑的时候这一系列动作看成一个动作集合。比如连接数据库来说:
加载驱动-----获取class--------获取连接对象-------访问数据库------查询---------操作结果
对于上面的这一系列动作我们把其中的虚线看成是一个个的切面。然后我们在虚线的位置上加入一些逻辑。哪怕是日志,这也就成就了在不知不觉中将逻辑处理加入到了相应的位置上。而形成了所谓的面向切面编程!
**下面通过@Before演示Aop织入到方法之前执行一些逻辑**
AOP的应用:
Xml配置 这里的xml配置引入了aop的xsd语法约束。另外加入的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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" >
<context:annotation-config/>
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring" />
<!-- 自动产生代理,内部实现是用AspectJ实现。可以使用aspectj的注解产生代理 -->
<aop:aspectj-autoproxy />
</beans>
~~~
加入Jar包:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-04_5729a8fe542b9.jpg)
**1、编写被注入的方法。必须得是spring容器管理的对象**
~~~
import org.springframework.stereotype.Component;
import com.spring.dao.UserDao;
@Component("userService")
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//在下面方法前面加逻辑
public void HelloWorld(){
System.out.println("helloworld");
}
}
~~~
**2、织入方法的配置:**
~~~
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//声明切面
@Aspect
//加入Spring管理容器
@Component("LogInterceptor")
public class LogInterceptor {
//指定织入的方法。
@Before("execution(public void com.spring.service.UserServiceImpl.HelloWorld())")
public void BeforeMethod(){
System.out.println("method start!");
}
}
测试aop的织入:
public class SpringTest {
@Test
public void test01() {
BeanFactory applicationContext = new ClassPathXmlApplicationContext(
"beans.xml");
UserService user = (UserService) applicationContext.getBean("userService");
user.HelloWorld();
}
}
~~~
**注意:**
在编写过程中的织入点语法上指定before织入哪个方法的前面。而括号中的这个被指定的织入点最好是实现一个接口。如果不实现接口的话就会报异常为:
Cannot proxy target class because CGLIB2 is not available.Add CGLIB to the class path or specify proxy interfaces
这个异常的解决办法为:
加入cglib.jar。因为被织入对象的方法单位如果没有实现接口的话它就需要cglib.jar的支持。
**AOP基本概念:**
JoinPoint:切入点、可以理解为上面案例的HelloWorld方法之前就为一个Joinpoint
Pointcut:切入点的集合,可以通过织入点语法定义N个切入点加入逻辑处理。
Aspect:切面,指的是切面的类。也就是上面声明Aspect的逻辑集合
Advise:指的是切面上的逻辑比如@Before、@After
Target:被代理对象.上面的案例指的是UserServiceImpl
Weave:织入
六、Spring自动装配注解@Autowired
最后更新于:2022-04-01 11:38:17
自动装配:
@Autowired使用自动装配的方式。将bean容器里面的值自动注入到bean中。
案例:
1、 Java文件:
~~~
public class UserAction {
@Autowired
private UserService userService;
//set方法还是不能缺的,因为autowired也是用setter注入的
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.HelloWorld();
}
}
~~~
2、 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
default-autowire="byName">
<bean id="userDao" class="com.spring.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.spring.service.UserServiceImpl" scope="prototype">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 不用再指定property,这里指明autowire就可以了。 -->
<bean id="userAction" class="com.spring.action.UserAction" autowire="byName">
</bean>
</beans>
~~~
值得注意的是。上面的这个byName还有一种方式为byType。
还有它标注的范围。不难看到在xml文件的声明部分有一个约束。这个是全局的约束。是为了避免繁琐性的重复工作而设置的,我想很容易看懂。在此不多说了。
五、Spring容器组建注解@Component和Resouces实现完全注解配置
最后更新于:2022-04-01 11:38:15
@Resource和@Component实现零XML配置
1、@Resource的注解:
@Resource是J2EE的注解。意思是说在容器里面找相应的资源。也可以通过name属性指定它name的资源。可以注解到field或者setter上面
~~~
public class UserAction {
private UserService userService;
@Resource(name="userService")
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.HelloWorld();
}
}
~~~
2、@Component
@Component和<context:component-scan base-package="com.spring"></context:component-scan>配合实现无XML配置,只通过注解配置及可将类放入资源容器中。
案例解析:
1、 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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.spring"></context:component-scan>
</beans>
~~~
2、 Java文件:
标注资源的注解@Component。括号里面指定的是存入容器的name属性为userService
那么将来我们拿的时候则getBean(“userService”)即可。如果我们不指定userService它默认存入容器bean的key为userServiceImpl这样就可以得到一个装有UserServiceImpl对象的容器
~~~
package com.spring.service;
import org.springframework.stereotype.Component;
import com.spring.dao.UserDao;
@Component("userService")
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void init(){
System.out.println("init");
}
public void destory(){
System.out.println("destory");
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void HelloWorld(){
System.out.println("helloworld");
}
}
~~~
通过@Resource将资源注入进来
因为上文已经配置了容器里面的资源。所以我这里将资源通过@Resource注解将资源注入到相关的属性。请看代码:
~~~
@Component("userAction")
public class UserAction {
private UserService userService;
//它会将beans的xml文件配置加入进去
//也可以使用name属性指定byName的指定
@Resource(name="userService")
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.HelloWorld();
}
}
~~~
测试实现:
通过上文配置的userAction案例来得到这个对象然后调用它里面的方法,因为上文通过了@ Component注解将UserAction的对象配置到了容器里面。所以获得容器之后就可以用这种方法getbean即可
~~~
@Test
public void test01(){
BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserAction user = (UserAction) applicationContext.getBean("userAction");
user.addUser();
}
@Scope和@PostConstruct、@PreDestroy
~~~
很简单就相当于前面讲到的作用于和initmethod和destorymethod请看下面代码。不再多说:
~~~
@Scope("Singleton")
@Component("userService")
public class UserServiceImpl implements UserService{
private UserDao userDao;
@PostConstruct
public void init(){
System.out.println("init");
}
@PreDestroy
public void destory(){
System.out.println("destory");
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void HelloWorld(){
System.out.println("helloworld");
}
}
~~~
四、基于Annotation的bean
最后更新于:2022-04-01 11:38:13
Annotation:
Dtd和xsd约束了xml文件的语法。这里引入了context前缀的标签语法.用来使用注解
通过引入context标签。运用注解来注入。请看下面的代码案例:
详细请看注释
1、 Xml代码:
~~~
<?xml version="1.0" encoding="UTF-8"?>
<!-- xsd文件,约束本xml可以用的标签 -->
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 运用上面引入的命名空间标签.初始化了4个bean
1、AutowiredAnnotationBeanPostProcessor
2、CommonAnnotationBeanPostProcessor
3、PersistenceAnnotationBeanPostProcessor
4、 RequiredAnnotationBeanPostProcessor
-->
<context:annotation-config/>
<bean id="userDao" class="com.spring.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.spring.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userAction" class="com.spring.action.UserAction">
</bean>
</beans>
~~~
2、 Java代码:
~~~
public class UserAction {
private UserService userService;
//Autowired使用的是byType类型的注入。如果配置文件中有两个bean的话那么将出现异常
@Autowired
//@Qualifier的value属性可以指定bean的name。这样的话就不怕配置2个bean和byName的原理一样。@AutoWired和@Qualifier配合使用可以
public void setUserService(@Qualifier(value="userService") UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.HelloWorld();
}
}
~~~
另外还有一个注解是@Required。在这里就不多说了。其实有和没有的意义都不是很大。大家有兴趣的话可以看一看Spring的API
三、Bean的懒加载和生命周期
最后更新于:2022-04-01 11:38:10
懒加载
~~~
<?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-2.5.xsd"
default-lazy-init="true">
<bean id="userDao" class="com.spring.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.spring.service.UserServiceImpl" scope="prototype">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 这里的懒加载。也就是说在我们程序中真正get指定bean的
时候才会实例化这个bean而且也有全局的声明在xml文件上,否则在容器初始化的时候就开始声明初始化实例了。 -->
<bean id="userAction" class="com.spring.action.UserAction" autowire="byName" lazy-init="true">
</bean>
</beans>
~~~
生命周期:
bean的声明周期是要在配置文件中指定并且要在bean中编写的。下面看两个文件:
1、 xml配置文件:
~~~
<bean id="userService" class="com.spring.service.UserServiceImpl" init-method="init" destroy-method="destory">
<property name="userDao" ref="userDao"></property>
</bean>
~~~
Java文件:
~~~
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void init(){
System.out.println("init");
}
public void destory(){
System.out.println("destory");
}
~~~
二、Ioc控制反转集合注入和Scope
最后更新于:2022-04-01 11:38:08
Scope:
Singleton:每次拿到的bean都是一个bean
Prototype:每次拿到的都是一个新的对象。在Action层推荐用Prototype
在xml的bean配置中指定Scope属性即可:如下代码
~~~
<bean id="userService" class="com.spring.service.UserServiceImpl" scope="prototype">
<property name="userDao" ref="userDao"></property>
</bean>
~~~
集合注入的案例:List、Set和Map
~~~
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource"/>
</list>
</property>
<property name="adminEmails">
<props>
<prop key="administrator">admin@some.org</prop>
<prop key="support">support@some.org</prop>
</props>
</property>
<property name="someMap">
<map>
<entry>
<key><value>yup an entry</value></key>
<value>just some string</value>
</entry>
<entry>
<key><value>yup a ref</value></key>
<ref bean="myDataSource">
</entry>
</map>
</property>
~~~
一、Ioc控制反转注入原理
最后更新于:2022-04-01 11:38:06
在spring中IOC控制反转是spring的一个重点内容下面我们通过一个简单的案例简单阐述一下springIOC的应用,这其中包括ID和name两种注入方法和基本属性的注入方法等标注在注释中:
1、 新建Java项目并且加入Jar包:
这一步我们首先要新建一个java项目然后导入相关的Jar包支持。在这里我说明一下要导入的Jar包:
分别是:
A、 Spring.jar内部包含控制反转的内容
B、 Commons-logging.jar是我们用来输出日志用的
2、 编写程序得到BeanFactory容器中的java对象
A、 编写要IOC的Java类
~~~
//类很简单。只有一个方法用来测试即可
public void addUser(){
System.out.println("============");
}
~~~
B、 编写beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="userAction" class="com.spring.action.UserAction" />
</beans>
~~~
C、 编写测试类JunitTestCase
~~~
@Test
public void test01(){
//得到容器对象
BeanFactory applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//得到配置的bean
UserAction user = (UserAction) applicationContext.getBean("userAction");
调用相关的方法
user.addUser();
}
~~~
输出结果:
============
Setter注入:原理同上。只不过是我们不new类里面的属性。而是只将他声明出来。然后将容器里面的值配置通过反射赋值过去即可:
在下面的类里面userService属性并没有new出来。但是它有一个set方法。赋值的方法也就是配置文件中指定的:
Java文件
~~~
public class UserAction {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.HelloWorld();
}
}
~~~
Xml配置文件:
~~~
<bean id="userService" class="com.spring.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<!—下面的ID可以换成name最大的区别就是name可以有特殊字符,而ID不可以有-->
<bean id="userAction" class="com.spring.action.UserAction">
<property name="userService" ref="userService">
<!—基本属性的注入方式-->
<value>helloworld</value>
</property>
</bean>
~~~
这里我们首先第一个指定了userService的bean。然后将这个bean按照property指定到了Action的属性值里面。也就是将值赋了过去。
另外注入的方式分为3种。Setter、constructor、Interface。
我们经常用的也就是Setter了。这里也就只介绍setter方法。
前言
最后更新于:2022-04-01 11:38:04
> 原文出处:[Spring入门系列](http://blog.csdn.net/column/details/springzhuanlan.html)
作者:[zhang6622056](http://blog.csdn.net/zhang6622056)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# Spring入门系列
> Spring入门系列