16监听器、Filter、Nginx、Spring、AOP
16监听器、Filter、Nginx、Spring、AOP-2018/07/30
- 1.监听器
- 监听web对象创建与销毁的监听器
- ServletContextListener
- HttpSessionListener
- ServletRequestListener
- 监听web对象属性变化
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 监听web对象创建与销毁的监听器
- 2.Filter
- 生命周期
- 当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
- 当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法.
- 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.
- 生命周期
- 3.Nginx
- 实现的负载均衡,满足用户访问量的需求
-
4.一些规范的问题
- 不要出现类似这样的import语句:import java.util.*;
- 列限制:80或100
- 一个项目可以选择一行80个字符或100个字符的列限制,除了下述例外,任何一行如果超过这个字符数限制,必须自动换行。
-
水平空白
- 分隔任何保留字与紧随其后的左括号(()(如if, for catch等)。
- 分隔任何保留字与其前面的右大括号(})(如else, catch)。
- 在任何左大括号前({),两个例外:
- @SomeAnnotation({a, b})(不使用空格)。
- String[][] x = foo;(大括号间没有空格,见下面的Note)。
- 在任何二元或三元运算符的两侧。这也适用于以下“类运算符”符号:
- 类型界限中的&(<T extends Foo & Bar>)。
- catch块中的管道符号(catch (FooException | BarException e)。
- foreach语句中的分号。
- 在, : ;及右括号())后
- 如果在一条语句后做注释,则双斜杠(//)两边都要空格。这里可以允许多个空格,但没有必要。
- 类型和变量之间:List list。
- 数组初始化中,大括号内分隔任何保留字与紧随其后的左括号(()(如if, for catch等)。
- 在任何左大括号前({),两个例外:
-
每个switch语句都包含一个default语句组,即使它什么代码也不包含
- 5.json补充
- JSON 数据的书写格式
- "firstName" : "John"等价于这条 JavaScript 语句:firstName = "John"
- JSON的使用
- 把JSON文本转换为JavaScript对象,JavaScript函数eval()可用于将JSON文本转换为JavaScript对象。
- var obj = eval ("(" + txt + ")");
- JSON 数据的书写格式
- 6.spring
- Spring的核心是控制反转(IoC)和面向切面(AOP)
- Spring就是一个大工厂,是用于生成bean
- 核心容器:beans、core、context、expression
- IoC:将由Spring创建对象实例--> IoC 控制反转(Inverse of Control)
- 配置文件
- 配置需要创建的对象
- id :用于之后从spring容器获得实例时使用的
- class :需要创建实例的全限定类名
-
<?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.xsd"> <!--
配置service <bean> 配置需要创建的对象 id :用于之后从spring容器获得实例时使用的 class :需要创建实例的全限定类名 --> <bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl"></bean> </beans>
- 配置文件
-
-
- 测试
- 1 获得容器
- String xmlPath = "com/itheima/a_ioc/beans.xml";
- ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
- 2获得内容 --不需要自己new,都是从spring容器获得
- UserService userService = (UserService) applicationContext.getBean("userServiceId");
- userService.addUser()
- 1 获得容器
- 测试
-
-
- DI:Dependency Injection,依赖注入
- 依赖:一个对象需要使用另一个对象
- 注入:通过setter方法进行另一个对象实例设置
- 配置文件
- <property> 用于进行属性注入
- name: bean的属性名,通过setter方法获得
- ref :另一个bean的id值的引用
<!-- 创建service --> <bean id="bookServiceId" class="com.itheima.b_di.BookServiceImpl"> <property name="bookDao" ref="bookDaoId"></property> </bean> <!-- 创建dao实例 --> <bean id="bookDaoId" class="com.itheima.b_di.BookDaoImpl"></bean>
- 静态工厂:静态工厂:用于生成实例对象,所有的方法必须是static * <bean id="" class="工厂全限定类名" factory-method="静态方法">
- 实例工厂:必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。 <bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService">
- DI:Dependency Injection,依赖注入
- 7.bean种类
-
- 普通bean:之前操作的都是普通bean。 ,spring直接创建A实例,并返回FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。
-
-
- bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。先创建FB实例,使用调用getObject()方法,并返回方法的返回值 FB fb = new FB(); return fb.getObject();
-
- 8.作用域
-
- singleton 单例,默认值。
- prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
- 9.生命周期
-
- 初始化和销毁
- 目标方法执行前和执行后,将进行初始化或销毁。
- <bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称">
- 目标方法执行前和执行后,将进行初始化或销毁。
-
- spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置
- <bean destroy-method="myDestroy" init-method="myInit" class="com.itheima.e_lifecycle.UserServiceImpl" id="userServiceId"/>
- 初始化和销毁
- 10.SpEL
-
- <property name="" value="#{表达式}">
- {123}、#{'jack'} : 数字、字符串
- #{beanId} :另一个bean引用
- #{beanId.propName} :操作数据
- #{beanId.toString()} :执行方法
- #{T(类).字段|方法} :静态方法或字段
-
集合的注入都是给添加子标签
-
数组:<array>
-
List:<list>
-
Set:<set>
-
Map:<map>
-
普通数据:<values>
-
引用数据:<ref>
-
- 大于小于分别用lt和gt代替
- 获取Collection 中的子集-通过条件筛选(注意新对象是一个新的 Collection)
- 筛选子集(.?[])
- 获取第一个(.^[])
- 获取最后一个(.$[])
- 集合的投影(.![])
- 如果想获得所有城市的名称组成的列表,可用操作<property name="cityNames" value="#{cities.![name]}"/>
- <property name="" value="#{表达式}">
- 11.构造方法
- <constructor-arg> 用于配置构造方法一个参数argument
- name :参数的名称
- value:设置普通数据
- ref:引用数据,一般是另一个bean id值
- index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
- type :确定参数类型
-
<!--例1:使用名称name--> <constructor-arg name="username" value="jack"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <!--例2:【类型type 和 索引 index】--> <constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg> <constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
- <constructor-arg> 用于配置构造方法一个参数argument
- 12.SET方法
- 普通数据
-
<property name="" value="值"></property>
<property name=""><value>值</value></property> -
两种方法等效
-
- 引用数据
- 两种方法等效
-
<property name="" ref="另一个bean"></property>
<property name=""><ref bean="另一个bean"/></ref></property>
- 普通数据
- 13.装配Bean 基于注解
- 1. @Component取代 @Component("id") 取代
- 2.web开发,提供3个@Component注解衍生注解(功能一样)取代<bean class="">
- @Repository :dao层
- @Service:service层
- @Controller:web层
- 3.依赖注入 ,给私有字段设置,也可以给setter方法设置
-
- 普通值:@Value("")
- 引用值:
- 方式1:按照【类型】注入 @Autowired
- 方式2:按照【名称】注入1 @Autowired @Qualifier("名称")
- 方式3:按照【名称】注入2 @Resource("名称")
-
-
4.生命周期
- 初始化:@PostConstruct
- 销毁:@PreDestroy
- 5.作用域
- @Scope("prototype") 多例
- 注解使用前提,添加命名空间,让spring扫描含有注解类
<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="com.itheima.g_annotation.a_ioc"> </context:component-scan> </beans>
-
4.生命周期
-
15.AOP:面向切面编程
- AOP是OOP(面向对象编程)的延续
- aop底层将采用代理机制进行实现。
- 接口 + 实现类 :spring采用 jdk 的动态代理Proxy。
- 实现类:spring 采用 cglib字节码增强。
- 目标类:接口 + 实现类
- 切面类:用于存通知 MyAspect
-
工厂类:编写工厂生成代理
- 目标类
- final UserService userService = new UserServiceImpl();
- 切面类 final MyAspect myAspect = new MyAspect();
-
代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面
- Proxy.newProxyInstance
- 参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。
- 一般情况:当前类.class.getClassLoader();
- 目标类实例.getClass().get...
- 参数2:Class[] interfaces 代理类需要实现的所有接口
- 方式1:目标类实例.getClass().getInterfaces() ;注意:只能获得自己接口,不能获得父元素接口
- 方式2:new Class[]{UserService.class}
- 例如:jdbc 驱动 --> DriverManager 获得接口 Connection
- 参数3:InvocationHandler 处理类,接口,必须进行实现类,一般采用匿名内部
- 提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke
- 参数31:Object proxy :代理对象
- 参数32:Method method : 代理对象当前执行的方法的描述对象(反射)
- 执行方法名:method.getName()
- 执行方法:method.invoke(对象,实际参数)
- 参数33:Object[] args :方法实际参数
- 提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke
- 参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。
- Proxy.newProxyInstance
-
代理类:采用cglib,底层创建目标类的子类
- 需要导包spring-core..jar
- 核心类 Enhancer enhancer = new Enhancer();
- 确定父类 enhancer.setSuperclass(userService.getClass());
- 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHandler接口
- intercept() 等效 jdk invoke()
- 参数1、参数2、参数3:以invoke一样
- 参数4:methodProxy 方法的代理 enhancer.setCallback(new MethodInterceptor(){ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {...}
- 创建代理 enhancer.create();
- 目标类
- 16.spring编写代理:半自动
- 导包:
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.apache.commons.logging-1.1.1.jar
- spring-aop-3.2.0.RELEASE.jar
- spring-beans-3.2.0.RELEASE.jar
- spring-context-3.2.0.RELEASE.jar
- spring-core-3.2.0.RELEASE.jar
- spring-expression-3.2.0.RELEASE.jar
- 切面类:采用“环绕通知” MethodInterceptor
- spring配置
- 创建目标类
-
<bean id="userServiceId" class="com.itheima.b_factory_bean.UserServiceImpl"></bean> <!-- 2 创建切面类 --> <bean id="myAspectId" class="com.itheima.b_factory_bean.MyAspect"></bean>
- 导包:
-
- 创建代理类
- 使用工厂bean FactoryBean ,底层调用 getObject() 返回特殊bean
- ProxyFactoryBean 用于创建代理工厂bean,生成特殊代理对象
- interfaces : 确定接口们。通过可以设置多个值,只有一个值时,value=""
- target : 确定目标类
- interceptorNames : 通知 切面类的名称,类型String[],如果设置一个值 value=""
- optimize :强制使用cglib <property name="optimize" value="true"></property>
<bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="com.itheima.b_factory_bean.UserService"></property> <property name="target" ref="userServiceId"></property> <property name="interceptorNames" value="myAspectId"></property> </bean>
- 创建代理类
- 17.aop编程
- 导入命名空间
- 使用 <aop:config>进行配置 proxy-target-class="true" 声明时使用cglib代理 <aop:pointcut> 切入点 ,从目标对象获得具体方法 <aop:advisor> 特殊的切面,只有一个通知 和 一个切入点 advice-ref 通知引用 pointcut-ref 切入点引用
- 切入点表达式 execution(* com.itheima.cspringaop..(..)) 选择方法 返回值任意 包 类名任意 方法名任意 参数任意
- 18.AspectJ 通知类型
- before:前置通知(应用:各种校验)
- 在方法执行前执行,如果通知抛出异常,阻止方法运行
- afterReturning:后置通知(应用:常规数据处理)
- 方法正常返回后执行,如果方法中抛出异常,通知无法执行
- 必须在方法执行后才执行,所以可以获得方法的返回值。
- around:环绕通知(应用:十分强大,可以做任何事情)
- 方法执行前后分别执行,可以阻止方法的执行
- 必须手动执行目标方法
- afterThrowing:抛出异常通知(应用:包装异常信息)
- 方法抛出异常后执行,如果方法没有抛出异常,无法执行
- after:最终通知(应用:清理现场)
- 方法执行完毕后执行,无论方法中是否出现异常
- 导入jar包
- 4个:aop联盟规范、spring aop 实现、aspect 规范、spring aspect 实现
- before:前置通知(应用:各种校验)