Spring,SpringMVC,Interceptor,AOP

Spring(撇除概念)

1,spring简单原理及IOC

jar包(pom)

		<dependencies>
		<!--SpringMVC核心包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>3.2.7.RELEASE</version>
		</dependency>
		<!--dom4j解析xml文件 -->
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>
		<!--DBCP数据库伴侣,连接池相关 -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<!--mysql连接包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.40</version>
		</dependency>
		<!--mybatis+spring+jdbc -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.8</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.1</version>
		</dependency>		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.2.8.RELEASE</version>
		</dependency>
		<!-- AOP -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.0</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjtools</artifactId>
			<version>1.8.0</version>
		</dependency>
		<!--jsp的标签 -->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jsp-api</artifactId>
			<version>9.0.2</version>
		</dependency>
		<!--jstl -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!--junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!-- jackson,JSON对象 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.8</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.8.5</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.8.1</version>
		</dependency>
 <dependency>
          <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
      <version>1.2</version>
                </dependency>
           <dependency>
             <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>5.0.0.RELEASE</version>
           </dependency>//为了RequestMapping等引入

引入spring的核心包spring-2.5.6.jar

1.1,对于Spring的对象管理原理有一个大概的了解,Spring管理的对象一般可以在xml里配置,自动扫描获得,注解标记等等

1.1.1,直接配置示例(在一个名为applicationcontext.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"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <bean id="A" class="beans.ParseXmlBeans">
    	<property name="str" value="qwertyuiop"></property>
    </bean>
</beans>

展示类的内容:已经初始化变量str

package beans;

public class ParseXmlBeans {

	private String str = "abcde";

	public String getStr() {
		return str;
	}

	public void setStr(String str) {
		this.str = str;
	}

	@Override
	public String toString() {
		return "ParseXmlBeans [str=" + str + "]";
	}
	
}

获取对象方法:(在xml文件里改变了str的取值)

	public void springTest() {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationcontext.xml");
		ParseXmlBeans pb = (ParseXmlBeans) ctx.getBean("A", ParseXmlBeans.class);
		System.out.println("输出:"+pb.toString());
		ctx.close();
	}

这就是spring管理对象的方法,通过读取配置的文件和注解,反射创建对象,也许这些创建的对象都是单例的,我们可以直接通过方法调用所有的对象,只要你给出正确的指示,这种用框架来管理获取对象的方式就是IOC依赖注入

1.1.2,XML配置(注意双引号)

1,Bean的实例化
<bean id=”user” class=”bean.User”/>
2,别名
<alias name=”user” alias=”user1” />两个同时都可以使用
3,饿汉,懒汉
<bean lazy-init="true" id=”user” class=”bean.User”/>
<bean eager-init="true" id=”user” class=”bean.User”>默认,生成对象的原点
4,作用域
<bean scope="singleton" id=”user” class=”bean.User”/>默认
<bean scope="prototype" id=”user” class=”bean.User”/>
<bean scope="request" id=”user” class=”bean.User” init-method="init" destroy-method="destroy"/>
5,生命周期回调
<bean id=”user” class=”bean.User” init-method="init" destroy-method="destroy"/>在User中写下,在初始化时调用init
在容器关闭之后调用destroy
6,setter注入和构造器注入(意味着你需要getset方法和构造器)
<bean id="userService" class="cn.ck.spring.service.UserService">
	<!-- property配置属性 -->
	<property name="dao" ref="userDao"></property>
</bean>
<bean id="userDao" class="cn.ck.spring.dao.UserDaoImpl"></bean>
<bean id=”user” class=”bean.User”>
	<property name=”id” >
		<null/>
	</property>
</bean>
<bean id="userService" class="cn.ck.spring.service.UserService">
	<!-- property配置属性 -->
	<constructor-arg index="0" ref="userDao"></constructor-arg>
      	<constructor-arg index="0">
		<value type="long">0</value>
	</constructor-arg>
</bean>
<bean id="userDao" class="cn.ck.spring.dao.UserDaoImpl"></bean>
7,自动装配
<bean id="userservice" class="cn.ck.spring.service.UserService" autowire="byName" />//byType
	<!-- byType???哈哈哈哈哈 -->
<bean id="dao" class="cn.ck.spring.dao.UserDaoImpl"></bean>
8,注入集合
<property name="listData">
	<list>
		<value>list-data-1</value>
		<value>list-data-2</value>
	</list>
</property>
<property name="setData">
	<set>
		<value>list-data-1</value>
		<value>list-data-2</value>
	</set>
</property>
<property name="mapData">
	<map>
		<entry key=”” value=””/>
	</map>
</property>
<property name="prop">
	<props>
		<prop key=”driver” >aaa</prop>
	</props>
</property>
9,文件配置的会直接把该properties文件中的数据配置到dbproperties
<util:properties id="dbproperties" location="classpath:dbproperties.properties"></util:properties>
10,Spring表达式
<bean id="target" class="cn.ck.spring.bean.TargetBean">
	<property name="id" value="#{source.id}"></property>
	<property name="name" value="#{source.name}"></property>
	<property name="city" value="#{source.list[0]}"></property>
	<property name="role" value="#{source.map.username}"></property>
	<property name="driver" value="#{source.dbConfig['driver']}"></property>
</bean>

1.1.3,自动扫描和注解驱动

在applicationcontext.xml文件的开头可以写上

   <!-- 配置全局扫描注解的驱动 -->
   <context:component-scan base-package="cn.ck.spring" />
   <mvc:annotation-driven />//必须要写

第一个指定包名,spring会主动扫描所有的类并创建对象,当你没有指定时,对象的调用名就是类名且首字母小写

第二个是注解的驱动,为注解的使用准备

1.1.4,注解

@Component:通用注解,类
@Named:通用注解,不推荐,类
@Controller:控制器的注解,类
@Service:业务逻辑的注解,类
@Respository:持久层的注解

以下注解用于对类的声明进行注解 @Scope / @Scope("singleton") / @Scope("prototype") @Lazy

以下注解用于对类中的方法的声明进行注解 @PostConstruct @PreDestroy

@Autowired
@Qualifier("userDao")
private IUserDao userDao;
@Autowired
public void setUserDao(@Qualifier("userDao") IUserDao userDao) {
    this.userDao = userDao;
}

@Resource(name=””)private IUserDao userDao;

@RequestMapping(“”)
@ResponseBody//返回的值将交给请求的一方
public TestAnno(@Value("")@Param("")String str, Map<String, String> map) {
	super();
	this.str = str;
	this.map = map;
}
@Value("")给参数赋值@Param("")参数的Spring框架内名称@RequestParam(“”)传来的值的名称
@AutoWired作为方法的注解可以达成方法参数的自动装配

......九牛一毛,有一些是springmvc注解

2,springmvc(包含拦截器,aop)


DispatcherServlet核心

HandlerMapping获取对象方法和请求路径放入其中

Controller

ModelAndView返回的结果

ViewResolver显示

2.1,web.xml-DispatcherServlet/ContextloaderListener

	<servlet>
		<description></description>
		<display-name>DispatcherServlet</display-name>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<description></description>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:conf/*</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

2.2,conf/applicationcontext.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"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
    <!-- 配置全局扫描注解的驱动 -->
    <context:component-scan base-package="cn.ck.spring" />
   <mvc:annotation-driven />//必须要写
    <!-- 配置ViewResolver组件 -->    <bean
    	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<property name="prefix" value="/WEB-INF/jsp/"></property>//设置前部地址
    	<property name="suffix" value=".jsp"></property>//设置后部文件名
    </bean>
    
    <!-- 读取db.properties -->
    <util:properties id="dbConfig" location="classpath:db.properties" />
    	
    <!-- 配置DBCP所需的Bean -->
    <!-- 各property中的name以类中的set方法名称为准 -->
    <bean id="ds" 
    	class="org.apache.commons.dbcp.BasicDataSource">
    	<property name="driverClassName" 
    		value="#{dbConfig.driver}"/>
    	<property name="url" 
    		value="#{dbConfig.url}"/>
    	<property name="username" 
    		value="#{dbConfig.user}"/>
    	<property name="password" 
    		value="#{dbConfig.password}"/>
    	<property name="initialSize" 
    		value="#{dbConfig.initsize}"/>
    	<property name="maxActive" 
    		value="#{dbConfig.maxsize}"/>
    </bean>
    <!-- 利用mybatis-spring配置sqlsessionfactory factorybean工厂bean,所以配置SqlSessionFactoryBean返回的是 SqlSessionFactory功能 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="ds"></property>
        <property name="mapperLocations" value="classpath:mapping/*.xml"></property>
    </bean>
    <!-- mybatis-spring提供了一个mapper接口自动扫描功能会自动找到全部的mapper接口, 并且为 每个接口创建一个对象,并且将对象作为bean存放在Spring容器中,如扫描IUserDao接口, 就会 自动创建一个bean存储到spring中,bean的id自动设置为iuserDao-class:org.mybatis.spring.mapper.MapperScannerConfigurer... -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        <property name="basePackage" value="cn.tedu.mybatis.dao"/>
    </bean>
</beans>

2.3,beans

2.4,Controller

2.5,Service

2.6,dao

2.7,interceptor

package cn.ck.spring.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class UserInterceptor implements HandlerInterceptor {//必须实现该接口

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
	}

	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		// TODO Auto-generated method stub
		//这里可以用来确认登录是否
		System.out.println("Interceptor1");
		HttpSession session=arg0.getSession();
		System.out.println(session.getId());
		if(session.getAttribute("username")==null) {
			System.out.println("FALSE");
			arg1.sendRedirect("#");
			return false;
		}else {
			System.out.println("TRUE");
			return true;
		}
	}

}

postHandle() 方法。该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap 来改变数据的展示。

applicationcontext.xml中配置

	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/*" />
			<mvc:exclude-mapping path="/login.do" />
			<mvc:exclude-mapping path="/handleLogin.do" />//除了这个路径
			<bean class="cn.tedu.spring.interceptor.UserInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

2.8,AOP

部分转载自https://www.cnblogs.com/liuruowang/p/5711563.html:珍惜阳光

一 AOP的基本概念

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类

二 通知类型介绍

(1)Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可

(2)AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值

(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名

来访问目标方法中所抛出的异常对象

(4)After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式

(5)Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint

三,application.xml中配置, 类,执行顺序,基于xml的配置

<aop:aspectj-autoproxy />
@Component
@Aspect
public class Operator {
    
    @Pointcut("execution(* com.aijava.springcode.service..*.*(..))")
    public void pointCut(){}
    
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("AOP Before Advice...");
    }
    
    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("AOP After Advice...");
    }
    
    @AfterReturning(pointcut="pointCut()",returning="returnVal")
    public void afterReturn(JoinPoint joinPoint,Object returnVal){
        System.out.println("AOP AfterReturning Advice:" + returnVal);
    }
    
    @AfterThrowing(pointcut="pointCut()",throwing="error")
    public void afterThrowing(JoinPoint joinPoint,Throwable error){
        System.out.println("AOP AfterThrowing Advice..." + error);
        System.out.println("AfterThrowing...");
    }
    
    @Around("pointCut()")
    public void around(ProceedingJoinPoint pjp){
        System.out.println("AOP Aronud before...");
        try {
            pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("AOP Aronud after...");
    }
  
}

-1.通知执行的优先级

进入目标方法时,先织入Around,再织入Before,退出目标方法时,先织入Around,再织入AfterReturning,最后才织入After。

注意:Spring AOP的环绕通知会影响到AfterThrowing通知的运行,不要同时使用!同时使用也没啥意义。

-2.切入点的定义和表达式

切入点表达式的定义算是整个AOP中的核心,有一套自己的规范

Spring AOP支持的切入点指示符:

execution:用来匹配执行方法的连接点

A:@Pointcut("execution(* com.aijava.springcode.service..*.*(..))")

第一个*表示匹配任意的方法返回值,..(两个点)表示零个或多个,上面的第一个..表示service包及其子包,第二个*表示所有类,第三个*表示所有方法,第二个..表示方法的任意参数个数

B:@Pointcut("within(com.aijava.springcode.service.*)")

within限定匹配方法的连接点,上面的就是表示匹配service包下的任意连接点

C:@Pointcut("this(com.aijava.springcode.service.UserService)")

this用来限定AOP代理必须是指定类型的实例,如上,指定了一个特定的实例,就是UserService

D:@Pointcut("bean(userService)")

bean也是非常常用的,bean可以指定IOC容器中的bean的名称

基于xml的配置:

<aop:config>
        <aop:aspect id="loggerAspect" ref="logger">
            <aop:around method="record" pointcut="(execution(* com.aijava.distributed.ssh.service..*.add*(..))
                                              or   execution(* com.aijava.distributed.ssh.service..*.update*(..))
                                              or   execution(* com.aijava.distributed.ssh.service..*.delete*(..)))
                                            and !bean(logService)"/>
        </aop:aspect>
</aop:config>

3,项目

......











猜你喜欢

转载自blog.csdn.net/caokangnsd/article/details/80676696