Spring框架学习

Spring框架

一、什么是Spring框架?

Spring框架是一个轻量级的IOC和AOP的容器框架,能够为企业级开发提供一站式服务。

  • 轻量级:大小只有2M,上手比较容易。
  • IOC:Spring框架的核心之一,称为控制反转,也叫依赖注入。
  • AOP:Spring框架的核心之一,称为面向切面编程。
  • 容器:可以创建对象,配置对象,并管理对象的整个生命周期。

二、IOC

(1)概念

IOC叫控制反转,是一种编程思想,简单的来说,就是原来创建对象和管理对象由程序员来完成,现在将创建对象和管理对象交给容器来完成。

(2)作用

IOC的主要作用就是为程序解耦,在创建对象是,通常来说是需要new一个对象,通过IOC,我们就可以不用写new了,通过特殊的标注就可以去掉new,这样也就有效的降低了程序的耦合度。这样就可以让开发者只关注自己的业务逻辑,更好的去进行扩展和维护。

三、IOC容器

在Spring中,IOC容器主要分为两种,BeanFactoryApplicationContext
(1)BeanFactory

BeanFactory是IOC容器的顶级接口,是IOC容器的最基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工作。

(2)ApplicationContext

ApplicationContext是Spring中的核心接口和容器,允许容器通过应用程序上下文环境创建、获取、管理bean。
该接口具有三个常用的实现类:

  • 1、ClassPathXmlApplicationContext:可以加载类路径下的配置文件,要求配置文件必须在类路径之下。
  • 2、FileSystemXmlApplicationContext:可以加载磁盘中任意路径下的配置文件,要求具有访问权限。
  • 3、AnnotationConfigApplicationContext:用于读取注解创建容器。

四、Spring中的重要注解

(1)@Component 组件,被标记的类会被Spring扫描到,交给Spring容器进行管理。
(2)@ComponentScan 组件扫描,标记在配置类上,用于扫描某一个包下带@Component的类。
(3)@Configuration 配置类,标记在类上,该类作为配置类代替XML。
(4)@Value 注入值类型数据,配置属性或set方法上。
(5)@Autowrie 自动装配,默认按类型进行注入。
(6)@Qualifier 标记名称,配置在类和注入属性上,用于区分类型相同的对象。
(7)@Resource 自动装配,类似Autowired,默认按名称注入,名称没有再按类型注入。
(8)@Repository 类似@Component,标记DAO实现类。
(9)@Service 类似@Component,标记Service实现类。
(10)@Controller 类似@Component,标记Controller类。

五、AOP

(1)概念

AOP叫面向切面编程,是OOP的一种重要补充,也是Spring的另一个核心。AOP关注横向关系,能够为多个相互没有关系,又都需要某些共同功能的类,提供一些通用服务(如:日志、权限、缓存、事务等)。

(2)作用

可以为代码解耦,将与类的核心业务无关,又都需要的功能封装起来,让类只关注自己的核心业务,分离了系统的核心业务和非核心业务。

(3)AOP中的核心术语

  • 1、切面(Aspect)
    对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为切面。
  • 2、连接点(joinpoint)
    被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
  • 3、切入点(pointcut)
    对连接点进行拦截的定义。
  • 4、通知(advice)
    所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
  • 5、目标对象(target)
    代理的目标对象,将切面应用到目标对象并导致代理对象创建的过程。
  • 6、引入(introduction)
    在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

(4)引入依赖
在使用前,需要引入以下依赖:

	<dependency>
		<groupId>org.springframework</groupId>
 		<artifactId>spring-aop</artifactId>
    	<version>5.2.8.RELEASE</version>
	</dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.9.5</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.5</version>
    </dependency>

(5)在AOP的XML配置文件中,我们需要引入以下标签

<!--配置包扫描-->
    <context:component-scan base-package="项目所在包"></context:component-scan>
    <!--配置提供服务的对象-->
    <bean id="pliceService" class="服务的对象所在的包"></bean>
    <!--AOP的配置-->
    <aop:config>
        <!--配置切入点    *代表任意长度字符   ..代表任意文件或者文件夹-->
        <aop:pointcut id="pointcut" expression="execution(* com..*.walk(..)) || execution(* com..*.study(..))" />
        <!--配置切面 ref配置服务的对象,也就是bean中的id-->
        <aop:aspect id="policeaspect" ref="pliceService">
            <!--配置前置服务-->
            <aop:before method="watch" pointcut-ref="pointcut"></aop:before>
            <!--配置后置服务-->
            <aop:after method="after" pointcut-ref="pointcut"></aop:after>
            <!--环绕通知-->
            <aop:around method="around" pointcut-ref="pointcut"></aop:around>
            <!--异常通知-->
            <aop:after-throwing method="afterThrow" pointcut-ref="pointcut" throwing="throwable"></aop:after-throwing>
            <!--返回通知-->
            <aop:after-returning method="afterReturn" pointcut-ref="pointcut"></aop:after-returning>
        </aop:aspect>
    </aop:config>

(6)AOP的注解配置

  • 1、@Aspect 切面,配置到切面类上
  • 2、@PointCut(“表达式”) 配置切入点,加在方法上
  • 3、@Before 配置前置通知方法
  • 4、@After 配置后置通知方法
  • 5、@Around 配置环绕通知方法
  • 6、@AfterReturning 配置后置返回值通知方法
  • 7、@AfterThrowing 配置后置抛出异常通知方法

六、编写日志跟踪

可以实时跟踪程序编写运行中遇到的bug以及所有的方法及参数。
(1)导如log4j的依赖

	<dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>

(2)编写log4j.properties配置文件

# ROOTER
log4j.rootLogger=DEBUG,CONSOLE,FILE

# CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} %-5p %-20c %x %t %m%n

# FILE
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs.log
log4j.appender.FILE.MaxBackupIndex=20
log4j.appender.FILE.MaxFileSize=10MB
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} %-5p %-20c %x %m%n

# ERROR
log4j.appender.ERR = org.apache.log4j.DailyRollingFileAppender
log4j.appender.ERR.File =error.log
log4j.appender.ERR.Append = true
log4j.appender.ERR.Threshold = ERROR
log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.ERR.layout = org.apache.log4j.PatternLayout
log4j.appender.ERR.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

(3)编写日志类

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Log_Config {

    //创建日志对象
    private Logger logger = Logger.getLogger(Log_Config.class);

    @Pointcut("execution(* com.eshop..impl.*Impl.*(..)) || execution(* com.eshop..*Servlet.*(..))")
    public void logPointcut(){

    }

    //配置环绕通知
    @Around("logPointcut()")
    public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable{
        //记录方法执行前时间
        long start  = System.currentTimeMillis();
        //获取方法名
        if (logger.isDebugEnabled()) {
            logger.debug(joinPoint.getSignature().getName());
        }
        //获取参数
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (logger.isDebugEnabled()){
                logger.debug("参数:"+arg);
            }
        }
        //获取返回值
        Object proceed = joinPoint.proceed();
        if (logger.isDebugEnabled()){
            logger.debug("方法返回值:"+proceed);
        }
        //获取执行时间
        long end = System.currentTimeMillis();
        if (logger.isDebugEnabled()){
            logger.debug("方法执行时间:"+(end - start));
        }
        return proceed;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值