使用Spring对Jersey进行AOP操作
使用Maven+Spring+Hibernate+Apache7+Jersey
遇到的问题:
1.Jersey如何AOP?
1.1首先测试了SpringMVC中Controller类如何AOP?
一直不成功,所以把execution改为execution(* com..*(..))
发现容器启动的时候执行构造方法,这时候AOP成功了,但是使用apache后就无法成功.
猜测原因可能是加载顺序,百度了一下是父子容器的关系,
一开始我是将Spring的所有xml分开的
applicationContext-dao.xml
applicationContext-service.xml
applicationContext-controller.xml
发现应该在web.xml中,
将有aop的放在首位,springMVC的放在下面,并且要提前扫描包
测试成功!
1.2使用jersey代替SpringMVC如何AOP?
根据上面的问题,猜测
只有Spring直接调用的方法,才能被AOP,首先应当让spring管理jersey,导包发现报错,
出现了好几个错误:应当这样操作来避免:
1.Spring的包要导全,特别是有一个spring-aop一开始忘记了
2.jersey-spring要写
如下
<!-- jersey-spring -->
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.19.4</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
3.web.xml中应当加上resource的包名
参考
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 让普通类获得session用的,还没成功 -->
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- 首先加载其他的spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-service.xml,classpath:applicationContext-dao.xml</param-value>
</context-param>
<!-- 再加载servlet -->
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.luhao.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- jersey-Servlet -->
<!-- <servlet> <servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet> <servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/*</url-pattern> </servlet-mapping> -->
<!-- SpringMVCServlet -->
<!-- <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-controller.xml</param-value>
</init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern>
</servlet-mapping> -->
</web-app>
如何在普通java类中获得Request或者Session?
暂时未解决
20180504更新,写了一个新的无Hibernate的项目,切入成功了
web代码如下:
代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-dao.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- spring管理的jerseyt -->
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.luhao.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.xml如下
<!-- 自动扫描包 -->
<context:component-scan base-package="com.luhao.*"></context:component-scan>
<!-- 配置切点 -->
<aop:config>
<aop:pointcut expression="execution(* com.luhao.resource.Test.test1(..))" id="mypoint1"/>
<aop:aspect ref="testAspect">
<aop:after method="test" pointcut-ref="mypoint1"/>
</aop:aspect>
</aop:config>
可以在切面获得request
加上listener之后,在切面类这样获得
方法一:HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
方法二:直接注入(也需要listenner)
@Autowired
private HttpServletRequest request
再加入Hibernate之后可以成功添加日志,整合后的ApplicationContext如下:
<?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"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd "> <!-- 定时任务 -->
<!-- 自动扫描包 -->
<context:component-scan
base-package="com.luhao.*"></context:component-scan>
<!-- 配置切点 -->
<aop:config>
<aop:pointcut
expression="execution(* com.luhao.resource.Test.test1(..))"
id="mypoint1" />
<aop:aspect ref="testAspect">
<aop:after method="test" pointcut-ref="mypoint1" />
</aop:aspect>
</aop:config>
<!-- 导入propertis文件 -->
<context:property-placeholder
location="classpath:db.properties"></context:property-placeholder>
<!-- 自动扫描包 -->
<!-- <context:component-scan base-package="com.luhao.entity"></context:component-scan> -->
<!-- Spring管理Hibernate第一步:配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${url}"></property>
<property name="username" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClassName" value="${driver}"></property>
</bean>
<!-- 使用c3p0连接池的配置 -->
<bean id="dataSource2"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driver}"></property>
<property name="maxPoolSize" value="20" />
<property name="minPoolSize" value="5" />
<!-- 初始化建立的连接数 -->
<property name="initialPoolSize" value="10" />
<!-- 最大空闲时间,120秒内未被使用的连接将被丢弃 -->
<property name="maxIdleTime" value="120" />
<!-- 当连接池耗尽,且未达到最大连接数时,一次获取的连接数 -->
<property name="acquireIncrement" value="2" />
<!-- 空闲检查时间间隔, 每隔120秒检查连接池里的空闲连接 ,单位是秒 -->
<property name="idleConnectionTestPeriod" value="60" />
</bean>
<!-- Spring管理Hibernate第二步:配置sessionFacoty -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource2"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">${hibernate.temp.use_jdbc_metadata_defaults}</prop>
</props>
</property>
<property name="packagesToScan" value="com.luhao.entity"></property>
</bean>
<!-- 数据库事务第一步:配置数据库管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 数据库事务第二步:配置事务增强 -->
<tx:advice id="transactionAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="regist" rollback-for="Execption" />
<tx:method name="login" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- 数据库事务第三步:配置切点 -->
<aop:config>
<aop:pointcut
expression="execution(* com.luhao.service.*.*(..))"
id="transactionPoint" />
<aop:advisor advice-ref="transactionAdvice"
pointcut-ref="transactionPoint" />
</aop:config>
</beans>