大致内容

    spring的bean管理(注解实现)
    AOP原理
    log4j介绍
    spring整合web项目的演示

一、spring注解实现bean管理

  注解:
    代码中一些特殊的标记,使用注解也可以完成一些相关的功能(写法"@")
    方法上、类上(详见基础加强) 

  使用注解创建对象,注入属性(完成day01相似的功能)
  可以使用注解,但不可能完全替代xml配置文件 【更新】 还真难说,有可能全注解无配置开发 

  准备工作:
    导入包:除了day01的6个核心jar包(当然包括日志的包)
        再加上aop的那个jar包(注解功能在里面),也就是图中红线的jar包

          

    创建User类和测试方法add():

public class User {

    public void add(){
System.out.println("注解的:add...");
}
} 

  创建xml文件后需要引入约束:
    除了第一天的beans约束;还需要一个用于注解的约束
    (也是找html文件夹最后一个文件),引入context的约束

  也就是打开xsd-configuration.html后找到这段复制进来 (已由springIDE替代)

     修改后的配置文件如下(还可以使用filter过滤器来进行过滤):

<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 ,scan就是扫描之意-->
<context:component-scan base-package="cn.anotation"></context:component-scan>
<!-- 只扫描属性上的注解,用的少 -->
<!-- <context:annotation-config></context:annotation-config> -->
</beans>

  准备工作准备完毕后,可以开始注解开发:
    1.注解创建对象:
     在要创建的对象的类上加注解:
     用 @Component(value="user")注解

    其它的配置文件中提到的这里也可以用注解实现,例如:bean的作用域 Scope="" 可以在类上加@Scope()注解
  虽然目前这3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。
  所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用上述注解对分层中的类进行注释。

  @Service 用于标注业务层组件 ===业务层

  @Controller 用于标注控制层组件(如struts中的action)===WEB层

  @Repository 用于标注数据访问组件,即DAO组件 ===持久层

  @Component 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

  可以加个注解,控制是单实例或者多实例
  在类上多加一行注解(内容参考昨天的,singleton但,prototype)
  @Scope(value="prototype") //设置是单实例还是多实例
 【更新!】spring的组件扫描可以侦测和实例化带有特定注解的类:

    对于扫描到的组件,spring有默认的命名策略(第一个字母小写),当然我们可以在注解后显式的声明名称 @Controller("userController")

    并且可以设置只扫描特定的类:

  可以为扫描的注解配置子节点:(可以有若干个)

<context:include-filter> 子节点表示要包含的目标类

<context:exclude-filter> 子节点表示要排除在外的目标类

  示例:

    <!-- @Service扫描 -->
<context:component-scan base-package="cn.service">
<context:exclude-filter type="annotation" expression="cn.service.ItemsService"/>
</context:component-scan>

  可以设置不使用默认的过滤器来达到效果:

<context:component-scan base-package="cn.service" use-default-filters="false">

 【更新】:设置只扫描controller注解

<!-- springMVC的配置文件,跳转逻辑有关的 -->
<context:component-scan base-package="cn.crud" use-default-filters="false">
<!-- 配置只扫描@Controller注解 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

 这样就会只扫描base-package指定下的有@Controller下的java类,并注册成bean

  实际上<context:component-scan> 元素还会自动注册 AutowiredAnnotationBeanPostProcessor 实例,

    该实例可以自动装配具有 @Autowired@Resource 、@Inject注解的属性.

  其中:@Autowired  会自动装配类型兼容的bean,构造器, 普通字段(即使是非 public), 一切具有参数的方法(set()方法等)都可以应用@Authwired 注解,注意set()方法时判断字段名称的方法

   当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false

  @Autowired

  当有多个匹配的实例时,会去匹配名称相匹配的,若再相同,则报错!

@Autowired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.

@Autowired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.

@Autowired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

【更新】 spring4的新特性:泛型依赖注入

  注解配置后的User类如下:

package cn.anotation;

import org.springframework.stereotype.Component;

/*@Scope(value="prototype") //设置是单实例还是多实例*/
@Component(value="user") //相当于原来的<bean id=use>r的配置
public class User { public void add(){
System.out.println("注解的:add...");
}
}

  2.注解注入属性:

  (之前用的是默认的byName形式),其中byName需要与set()方法对应,而不是和属性名称对应
  还是使用service中注入dao对象(对比day01的xml的配置实现)
  对比xml实现步骤:还是需要先创建对象,再实现注入
  先在两个类上加类注解
  再在service中加dao成员变量dao,给成员变量加注解而无需set()方法:

  类型有 byName byType:

    配置文件中不能有俩个相同的id,否则容器启动失败
  主要有两个属性装配的注解:
    @Autowried :自动注入找到对象的方式是根据类名找的对象进行注入——适用于单实现,底层原理是byType,可以利用@Qulifiler 来指定名称

  1. @Autowired
  2. @Qualifier("baseDao")
  3. private BaseDao baseDao;
  4. 在配置文件中使用:

    <qualifier value=""></qualifier>

    甚至 ,,可以将此注解应用在list map(key 必须是String)
    (与dao的类注解的value值无关),比较不直观,没有指定对象
    【注解更清晰】@Resource(name="要注入的对象名(dao的类注解的value值)")——适用于多实现

            这是由JavaEE5提供的

      一般而言,dao与daoImpl使用注解时需要在实现类中指定名称为接口
    若与value值不一样会报错(找错比较快的方式是找Casue By这一行,错误最准确)

  JSR330 的Inject 待补充

注解配置完成后的service和dao类如下:

package cn.anotation;

import org.springframework.stereotype.Component;

@Component(value="userDao")
public class UserDao { public void add(){
System.out.println("dao.add()");
}
}
package cn.anotation;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

@Service(value="userService")
public class UserService { //定义成员属性,无需set()方法,直接对属性加注解即可
//@Autowired
@Resource(name="userDao")
private UserDao dao;
public void add(){
System.out.println("service.add()");
dao.add();
}
}

  做个简单的测试如下:(请勿将测试类名命名为Test)

package cn.anotation;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test01 { //注解创建对象
@Test
public void test(){
//加载spring核心配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
//得到配置创建的对象
User user =(User)context.getBean("user");
user.add();
}
//注解注入属性
@Test
public void test02(){
//加载spring核心配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
//得到配置创建的对象
UserService service =(UserService)context.getBean("userService");
service.add();
} }

  配置文件和注解混合使用:
    一般创建对象使用配置文件
    属性注入使用注解的方式
    案例cn.xmlandano包下,使用bean2.xml配置文件
    步骤也是建立类,创建对象使用xml,而属性注入使用注解

  采用service中注入两个dao,三个类和配置文件如下:

  BookDao:

package cn.xmlandano;

public class BookDao {

    public void buy(){
System.out.println("dao.buy()");
}
}

  OrderDao:

package cn.xmlandano;

public class OrderDao {

    public void buy(){
System.out.println("order.buy()");
}
}

  BookService:

package cn.xmlandano;

import javax.annotation.Resource;

public class BookService {

    //使用注解注入属性
@Resource(name="bookDao")
private BookDao bookDao;
@Resource(name="oderDao")
private OrderDao orderDao;
public void buy(){
System.out.println("service.buy()");
bookDao.buy();
orderDao.buy();
}
}

  配置文件:

<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 ,scan就是扫描之意-->
<context:component-scan base-package="cn"></context:component-scan>
<!-- 创建对象 -->
<bean id="bookService" class="cn.xmlandano.BookService"></bean>
<bean id="bookDao" class="cn.xmlandano.BookDao"></bean>
<bean id="oderDao" class="cn.xmlandano.OrderDao"></bean>
</beans>

    测试类与上一个测试类类似,不再赘述。

  【更新】 @Configuration 和@Bean的使用 :

    用于定义一个配置类,用@Configuration注解该类,等价 与XML中配置beans;用@Bean标注方法等价于XML中配置bean。

    具体请参见网友博文:http://blog.csdn.net/vvhesj/article/details/47661001

二、AOP   

  1)AOP概述
  2)AOP底层原理
  3)AOP相关术语
  4)AOP操作  

  1)AOP概述:面向切面编程
    struts2中的第一个浅的层面:不修改源代码拓展功能
    AOP采取横向抽取机制,取代传统的纵向继承体系的重复性代码——抽取横切关注点

代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀. 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.

代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化, 必须修改所有模块.

  2)AOP底层原理:
    例如有一个这样的Service的类和add()方法

public class UserService(){
public void add(){
//添加用户逻辑
}
}

    现在想要为add()方法添加日志功能,需要在add()方法内部加入实现代码;
    如果有很多方法(update.delete...)等很多方法都要重复性加,不可取!

    第一阶段的纵向的解决方案是新建一个类UserLog 定义实现log()日志方法;
    其它类想要实现采用继承UserLog类
    UserService extends UserLog
    于是可以调用父类的方法实现日志功能:super.log();
    缺陷是例如方法名称发生了变化,则所有的子类的调用代码都要修改

    AOP解决方案是横向抽取机制(底层动态代理)
    动态代理做的主要的事情是进行方法的增强;
  第一种情况:有接口的情况,使用jdk动态代理
    使用动态代理创建接口实现类和代理对象,例如有一个interface Dao 和 class DaoImpl implements Dao
    创建一个和DaoImpl平级的对象,但是这个不是真正的对象而是一个代理对象,但代理对象和原对象有相同的功能
  第二种情况:没有接口的情况,cglib动态代理
    创建User类的子类的代理对象,在子类中可以调用父类的方法完成增强 

  3)AOP相关术语(重点掌握的为带*的)
    Joinpoint:连接点
        类里面哪些方法可以被增强,这些方法就称为连接点
    *Pointcut:切入点
        在类中可以有很多方法被增强,在实际操作中只增强了部分方法,实际增强的方法就称为切入点
    *advice:通知/增强
        例如之前想要加log()日志功能,这个日志功能就叫增强,也就是实际拓展的功能的逻辑
        通知/增强分为:例如要增强add()方法
      前置通知:在方法之前
      后置通知:在方法之后(无论方法是否出现异常),执行结果在最终通知厘米
      异常通知:在出现异常后通知(用的少)
      最终通知:在后置之后执行
      环绕通知:方法前、后都要执行(例如计算方法执行时间)

    【更新】 前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。 
        正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。 
        异常返回通知[After throwing advice]:在连接点抛出异常后执行。 可以使用异常作为入参,当出现指定异常时才执行(add(NullPointException ex))
        返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。 
        环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。

      需要带ProcedingJointPoint参数(功能最强大,但却不代表最常用) ,类似于动态代理,并且必须有返回值,返回值为目标方法返回值

环绕的前置后置返回异常通知都可以做

    切面优先级:如果有多个切面,优先级如何确定呢?可以在增强的类上(切面)使用@Order注解,其中的参数值越小优先级越高,例如@Order(1)

    *Aspect:切面
        把增强应用到切入点的过程,这个过程就叫切面。例如在add()方法上增强一个日志功能

  【更新】:AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。
    剩下几个作了解:
        引介,目标对象,织入(把增强应用到类的过程),代理

  【更新】:慕课网友测试的顺序:

        经测试,当有配置around时,after和after-returning的执行顺序和它们在xml文件中配置顺序相反。

  4)spring的AOP操作(达到会用):
    使用AspectJ进行AOP操作,AspectJ是一个面向切面的框架,springAOP本身是为了提供整合
    经常被用来和spring一起使用来进行AOP的操作,虽然它本身不是spring的一部分

  使用aspectJ实现AOP操作主要有两种方式:
    1.基于aspectJ的xml配置
    2.基于aspectJ的注解实现(day03补充),更方便,更简洁

  AOP操作准备工作:
  导入AOP相关的jar包
    aop asp.. spring-asp spring-aop详见spring02项目(此时有如图10个jar包了)

  创建核心配置文件,导入AOP的约束(bean3.xml)找约束不再赘述

  实际操作:
    建两个类:基础的类Book 增强的类 BuyBook

package cn.aop;

//AOP操作
public class Book { public void buy(){
System.out.println("买书");
}
}
package cn.aop;

import org.aspectj.lang.ProceedingJoinPoint;

//增强book类
public class BuyBook { public void before1(){
System.out.println("买书前");
}
//环绕通知可以使用一个参数
public void around(ProceedingJoinPoint pj) throws Throwable{ System.out.println("方法之前-环绕"); //执行被增强的方法
pj.proceed(); System.out.println("方法之后-环绕");
}
}

    //这里也可以给环绕通知配置另外的和被增强方法的参数列表,来取得被增强方法的参数

  使用表达式配置来配置切入点(增强的方法),也可以在配置文件中配置order等和注解一样的操作

bean3.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置对象 -->
<bean id="book" class="cn.aop.Book"></bean>
<bean id="buyBook" class="cn.aop.BuyBook"></bean>
<!-- 配置aop操作 -->
<aop:config>
<!-- 1.配置切入点,express为配置表达式 id为切入点的名字 -->
<aop:pointcut expression="execution(* cn.aop.Book.buy(..))" id="pointcut1"/>
<!-- 2.配置切面(增强的过程) ref属性为增强的对象-->
<aop:aspect ref="buyBook">
<!-- 前置增强 ,method指定增强类的哪个方法作为前置增强,pointcut-ref为要增强的切入点-->
<aop:before method="before1" pointcut-ref="pointcut1"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>

  常用AOP表达式:
    格式:execution(<访问修饰符>?<返回值><方法名>(参数)<异常>)——方法签名
    一般 访问修饰符写 *
    后面接方法的全路径
  例如:注意的点:可以使用通配符, *后加空格以示区分
  注意参数里是..两个点,表示参数包含在里面
  execution(* cn.aop.Book.add(..)) ——易知这里 * 代表任意修饰符和任意返回值,后面代表任意参数(具体写的话可以写 add(int, int))
  execution(* cn.aop.Book.*)
  匹配所有以save开头的方法
  execution(* save*(..))

   【更新】 切入点表达式可以使用 && ||等进行组合连接的运算(但是不建议)

    完整AOP表达式语法,参考http://blog.csdn.net/qq525099302/article/details/53996344

  表达式重用:PointCut的定义(适用于注解方式)

  当然,有时候我们知道切入点表达式是可以重用的,那么如何重用呢?可以通过定义一个专门的方法,示例既相关说明如下(如果不在相同包,需要指定包名):

/**
* 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.
* 使用 @Pointcut 来声明切入点表达式.
* 后面的其他通知直接使用方法名来引用当前的切入点表达式.
*/
@Pointcut("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")
public void declareJointPointExpression(){} /**
* 在 com.atguigu.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码
*/
@Before("declareJointPointExpression()")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object [] args = joinPoint.getArgs(); System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
}

    具体配置及解释见bean3.xml
      配置略显麻烦,后期引入注解形式!
  后置通知类似不再赘述
  环绕通知:
  比较特别的是增强方法的写法(注意一个参数),配置文件同理

  作个简单测试:

package cn.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test03 { @Test
public void test(){
//加载spring核心配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
//得到配置创建的对象
Book book =(Book)context.getBean("book");
book.buy();
}
}

【更新】(引自慕课评论):我听了两个小时,终于听懂了老师要讲的东西。让我来说一下这节课的内容:Introductions Advice简介通知。简介通知的主要配置是:声明一个接口A,再声明一个实现接口A的实现类B,并且用types-matching指定当前的这个简介通知所关联的业务类。然后通过implement-interface属性把接口A强制作为这些业务类的父类。在单元测试中,用getBean(beanId)方法得到业务类,然后把这个业务类强制转换成接口A类型,然后调用接口A的实现类B的方法。简介通知的用途我认为是:在业务逻辑操作中将横向的执行顺序改变为纵向的处理日志,事务相关的服务,通过类B实现这些服务的具体实现

三、log4j介绍
  (之前一直有警告)
  通过log4j可以看到程序运行过程中更详尽的信息
  (哪些对象被创建了,什么配置文件被修改了以及一些错误信息等等)

  使用的步骤:
    导包(之前已导)
    复制log4j的配置到src下(只需看懂,无需手写)
  之前没加配置文件它就不知道该以什么样的格式输出
    rootLogger 日志级别
      INFO 基本信息
      DEBUG 详细信息
    //log4j待补充

这里贴出一个log4j.properties简单示例(注意修改一些例如路径等参数):

# Set root logger level to WARN and append to stdout
log4j.rootLogger=WARN, stdout, error
#WARN\u4E3Alog\u8F93\u51FA\u7EA7\u522B\uFF0Cstdout\uFF0Cerror\u4E3A\u8BE5log\u7684\u522B\u540D\uFF0C\u4E0B\u9762\u5C06\u7528\u5230
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%c:%L) - %m%n # Print only messages of level ERROR or above in the package noModule.
log4j.logger.noModule=FATAL # OpenSymphony Stuff
log4j.logger.com.opensymphony=INFO
log4j.logger.com.opensymphony.webwork=DEBUG # Spring Stuff
log4j.logger.org.springframework=INFO #################################
# \u9519\u8BEF\u4FE1\u606F #
#################################
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.File=F:/errors.log
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=[%d]-%-5p (%F:%L)|%m%n
log4j.appender.error.DatePattern='.'yyyy-MM-dd
log4j.appender.error.Threshold=ERROR ###################################
# CONSOLE #
################################# log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=(%F:%L)|%m%n log4j.appender.errorcsle=org.apache.log4j.ConsoleAppender
log4j.appender.errorcsle.layout=org.apache.log4j.PatternLayout
log4j.appender.errorcsle.layout.ConversionPattern=%-5p (%F:%L)|%m%n
log4j.appender.errorcsle.Threshold=ERROR ##################################
# \u4E1A\u52A1\u7CFB\u7EDF #
#################################
log4j.logger.cn.vesung=DEBUG, logic log4j.appender.logic=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logic.File=F:/logic.log
log4j.appender.logic.layout=org.apache.log4j.PatternLayout
log4j.appender.logic.layout.ConversionPattern=[%d]-%-5p (%F:%L)|%m%n
log4j.appender.logic.DatePattern='.'yyyy-MM-dd

//Log4j的详细介绍请见另一篇博客

四、Spring整合web项目
  在action里调service,service里调dao;
  service里调dao可以用属性注入;
  在spring02_web里演示
    导包:
  先导入struts2和spring的jar包

  建立action(继承ActionSupport) service(依赖注入dao) dao

  在action中测试:action在struts.xml中配置(一定要配置过滤器!!!,不然404)

目录结构如下:

  

UserDao:

package cn.dao;

public class UserDao {

    public void add(){
System.out.println("dao.add");
}
}

UserService:

package cn.service;

import cn.dao.UserDao;

public class UserService {

    private UserDao dao;

    public void setDao(UserDao dao) {
this.dao = dao;
} public void add(){
System.out.println("service.add");
dao.add();
}
}

UserAction:

package cn.action;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.opensymphony.xwork2.ActionSupport; import cn.service.UserService; public class UserAction extends ActionSupport{ @Override
public String execute() throws Exception {
//在action中测试
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
UserService service = (UserService) context.getBean("userService");
service.add();
return NONE;
}
}

struts.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="demo01" extends="struts-default" namespace="/">
<action name="userAction" class="cn.action.UserAction">
</action>
</package>
</struts>

spring的bean1.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-4.3.xsd"> <!-- 创建service -->
<bean id="userService" class="cn.service.UserService">
<!-- 注入dao -->
<property name="dao" ref="dao"></property>
</bean>
<!-- 创建dao -->
<bean id="dao" class="cn.dao.UserDao"></bean>
</beans>

会出现一个小问题,通过log4j可以看到,每次访问都要 创建对象加载文件等
可以通过在服务器启动时就加载完成,把服务器给压力
整合的基本原理第一天已有介绍这里直接贴过来:

这个问题spring已经给我们封装好了

===spring整合web项目
Hibernate时有一个遗留问题:sessionFactory的创建会比较慢,可以交给服务器来创建
还有上面的bean1.xml每次都要加载spring核心配置文件,会影响性能
以上的类似问题,解决的实现思想都是:
把加载配置文件和创建对象在服务器启动时就创建,把压力给服务器
spring中封装了相关的处理类,这里简单介绍原理:

web阶段中有一个与天地同寿的对象 ServletContext
它的创建可以由监听器进行监听
在服务器启动的时候,服务器会为每个项目创建一个独一无二的对象:ServletContext
可以使用监听器对ServletContext进行监听,可以知道对象的创建时间
于是可以在监听器监听到ServletContext创建后
加载spring配置文件,把配置文件中配置的对象进行创建
对象创建后将创建的对象放在ServletContext中(它也是一个域对象)
域对象的存取数据直接使用get/setAttribute()即可

一个监听器,只需要配置这个监听器即可
在web.xml中,使用listener配置:
要整合web项目,还要一些整合的jar包:spring-web的包
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这里需要指定加载spring配置文件的位置
(不然会去默认的路径下找默认的文件)WEB-INF/applicatonContext.xml
<!-- 指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean1.xml</param-value>
</context-param>
这个参数名称去监听器的父类的常量中找

这里贴出web.xml的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>spring02_web</display-name>
<!-- 指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean1.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

Spring第二天——IOC注解操作与AOP概念的更多相关文章

  1. Spring框架学习之注解配置与AOP思想

         上篇我们介绍了Spring中有关高级依赖关系配置的内容,也可以调用任意方法的返回值作为属性注入的值,它解决了Spring配置文件的动态性不足的缺点.而本篇,我们将介绍Spring的又一大核心 ...

  2. Spring顾问、IOC注解和注解增强

    一.顾问 通知的一种表现方式(顾问包装通知/增强) Advisor: 名称匹配方法: NameMecthMethodPointcutAdvisor 1.定义了一个业务类 package cn.spri ...

  3. Spring自学教程-IOC、DI、AOP(二)

    一.spring的IOC-就是怎样使用spring来创建对象 二.springDI(依赖注入)-就是怎样给属性赋值 通过set方式赋值 以下我们只需要记住两点的赋值,基本类型和引用类型的赋值 基本类型 ...

  4. Spring框架之IOC(控制反转)

    [TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...

  5. IOC和DI,AOP的本质理解

    IOC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IOC容器),是框架共有的特性. 对于IOC的理解,可以把IOC看作是一个生产和管理bean对象的容器.原 ...

  6. Spring入门(二)— IOC注解、Spring测试、AOP入门

    一.Spring整合Servlet背后的细节 1. 为什么要在web.xml中配置listener <listener> <listener-class>org.springf ...

  7. Spring框架中的aop操作之一 及aspectjweaver.jar与aopalliance-1.0.jar下载地址 包含beans 注解context 和aop的约束

    (aspect oriented programming面向切面编程) 首先在原有的jar包: 需Spring压缩包中的四个核心JAR包 beans .context.core 和expression ...

  8. 一步一步深入spring(5)--使用基于注解的spring实现 AOP

    1.要利用spring aop,至少需要添加以下jar包 使用spring需要的jarspring.jar .commons-logging.jar 使用切面编程(AOP)需要的jar aspectj ...

  9. Spring学习笔记IOC与AOP实例

    Spring框架核心由两部分组成: 第一部分是反向控制(IOC),也叫依赖注入(DI); 控制反转(依赖注入)的主要内容是指:只描述程序中对象的被创建方式但不显示的创建对象.在以XML语言描述的配置文 ...

随机推荐

  1. Django 添加自定义包路径

    在设置文件里: import sys sys.path.insert(0,os.path.join(BASE_DIR,"要导包的目录名")) 用pycharm时,如果导包后没有自动 ...

  2. 如何使用CSS进行网页布局(HTML/CSS)

    什么叫做布局? 又称为版式布局,是网页UI设计师将有限的视觉元素进行有机的排列组合. 题目:假设高度已知,请写出三栏布局,其中左栏和右栏宽度各为300px,中间自适应 1.浮动布局 <!DOCT ...

  3. CSS3 响应式web设计,CSS3 Media Queries

    两种方式,一种是直接在link中判断设备的尺寸,然后引用不同的css文件: <link rel="stylesheet" type="text/css" ...

  4. [翻译] FeSpinner

    FeSpinner The loader collection for iOS app. 收集的iOS加载动画. REQUIREMENT FeSpinner work on any version i ...

  5. Python静态方法实现单实例模式

    单实例模式 当程序中需要同一个实例就可以解决问题的场景,可以使用单实例模式

  6. pandas模块安装问题笔记

    1. # pip install  pandas 引用 pandas 时,没有模块 ,进行模块安装,出现一推英文提示 结果 Collecting pandas Could not fetch URL ...

  7. Office 365实现单点登录系列(4)—安装AD FS

    单一登录 (Single Sign-On)简而言之,就是让用户使用一套ID和密码,就可以登录一个或多个系统的授权机制.用户只需要通过其中一个应用的安全认证之后,再访问同一服务器其他应用的资源时不需要再 ...

  8. shell study

    目录 shell记录 执行脚本 变量使用 注释 shell传递参数 运算符 echo printf test 流程控制 if ... else ... for while until case 跳出循 ...

  9. Gitflow 工作流简介

    Gitflow工作流简介 Gitflow工作流通过为功能开发.发布准备和项目维护分配独立的分支,让发布迭代过程更流畅. Gitflow工作流定义了一个围绕项目发布的严格分支模型,它会相对复杂一点,但提 ...

  10. Leetcode Weekly Contest 86

    Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个 ...