Spring框架学习小结

本文介绍了Spring框架的核心概念,包括其轻量级特性、控制反转IoC和面向切面编程AOP。详细阐述了DI、AOP的原理,并提供了使用注解实现IoC和AOP的代码示例,展示了如何通过注解在方法执行前后添加日志记录。此外,还提到了Spring框架的其他优势,如低耦合度和与第三方框架的整合能力。
摘要由CSDN通过智能技术生成

目录

一.什么是Spring框架

二.使用Spring的优点

三.Spring体系结构 

  四.Spring两大核心技术

 五.异常抛出增强、最终增强、环绕增强的使用方法

六.构造注入

 七.使用注解的方式实现IoC

 八.使用注解的方式实现AOP

九.总结


 

一.什么是Spring框架

是一个轻量级的企业级应用框架

企业应用开发的"一站式"选择,贯穿于表现层、业务层、持久层

Spring框架是一个开源的Java应用程序框架,它提供了一系列的功能和组件,能够帮助开发者快速构建可扩展的企业级应用程序

Spring框架由多个模块组成,每个模块都提供了一个特定的功能,包括核心容器、数据访问、Web、AOP、消息、测试等。

二.使用Spring的优点

优点:

低侵入式设计

独立于各种应用服务器

依赖注入特性将组件关系透明化,降低耦合度

面向切面编程特性允许将通用任务进行集中式处理

与第三方框架的良好整合

三.Spring体系结构 

  四.Spring两大核心技术

控制反转(IoC:Inversion of Control)/依赖注入(DI:Dependency Injection)

面向切面编程(AOP:Aspect Oriented Programming)

 

控制反转(IoC) 创建对象的控制权转移,是一种程序设计思想

依赖注入(DI) 将依赖的对象注入到需要的类中去,是"控制反转"设计思想的具体实现方式

面向切面编程(AOP)(如下参考)

public class UserServiceImpl implements UserService {
	private static final Logger log = Logger.getLogger(UserServiceImpl.class);
	public boolean save(User user){
		log.info(" 添加用户" + user.getUsername());//记录日志
		SqlSession sqlSession = null;
		boolean flag = false;
		try{ //异常处理
			sqlSession = MyBatisUtil.createSqlSession();
			if(sqlSession.getMapper(userMapper.class).add(user) > 0)
				flag = true;
			sqlSession.commit();//事务控制
			log.info(" 成功添加用户" + user.getUsername());
		} catch (Exception e){
			log.error(" 添加用户" + user.getUsername() + " 失败", e); //记录日志
			sqlSession.rollback(); //事务控制
			flag = false;
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		return flag;
	}
}

AOP目标

让我们专注于业务功能处理

AOP原理

将复杂的需求分解出不同方面,将不同对象、不同模块之间的共同业务集中解决 通过动态代理的方式,把抽离出来的共性代码"织入"到业务代码中,实现对原有代码的增强处理

下面是一个Spring AOP的完整例子,实现了一个简单的日志记录功能:

首先,定义一个接口和实现类:

public interface UserService {
    void addUser(String name);
    void updateUser(String name);
    void deleteUser(String name);
}

@Service
public class UserServiceImpl implements UserService {

    @Override
    public void addUser(String name) {
        System.out.println("Add user: " + name);
    }

    @Override
    public void updateUser(String name) {
        System.out.println("Update user: " + name);
    }

    @Override
    public void deleteUser(String name) {
        System.out.println("Delete user: " + name);
    }
}

 然后,定义一个切面类,并在其中定义一个日志记录方法:

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.UserService.*(..))")
    public void log(JoinPoint joinPoint) {
        System.out.println("Logging " + joinPoint.getSignature().getName() + " method");
    }
}

其中,@Aspect用于将该类标记为切面类,@Before("execution(* com.example.UserService.*(..))")表示在UserService接口中的所有方法执行之前,执行log方法。

最后,在Spring配置文件中加入AOP的配置:

<!-- 开启AOP自动代理 -->
<aop:aspectj-autoproxy />

<!-- 注册切面 -->
<bean id="loggingAspect" class="com.example.LoggingAspect" />

 现在,可以通过调用UserService接口中的方法来测试AOP的效果:

@Autowired
private UserService userService;

@Test
public void test() {
    userService.addUser("Alice");
    userService.updateUser("Bob");
    userService.deleteUser("Charlie");
}

执行结果如下:

Logging addUser method
Add user: Alice
Logging updateUser method
Update user: Bob
Logging deleteUser method
Delete user: Charlie

可见,在AOP的作用下,每次方法执行前都会输出一条日志记录。

小结:

 五.异常抛出增强、最终增强、环绕增强的使用方法

异常抛出增强:

异常抛出增强是 AOP 中的一个通知类型,用于在方法抛出异常时执行一些处理逻辑。它的使用方法如下:

@Aspect
public class ExceptionHandlerAspect {
  @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
  public void handleException(Exception ex) {
    // 处理逻辑
  }
}

在上面的例子中,@AfterThrowing 声明了一个异常抛出增强,它的 pointcut 属性表示匹配 com.example.service 包下的所有方法,throwing 属性表示在抛出异常时需要传递一个 Exception 类型的参数。在处理逻辑中,可以获得抛出的具体异常,并进行相应的处理。

最终增强:

最终增强是 AOP 中的一个通知类型,它的作用是在方法执行结束后执行一些操作,无论方法是否抛出异常。最终增强的使用方法如下:

@Aspect
public class FinallyAspect {
  @After("execution(* com.example.service.*.*(..))")
  public void after() {
    // 处理逻辑
  }
}

在上面的例子中,@After 声明了一个最终增强,它的 pointcut 属性表示匹配 com.example.service 包下的所有方法。在处理逻辑中,可以编写任何需要在方法结束后执行的操作。

环绕增强:

环绕增强是 AOP 中最为强大的通知类型,它可以在方法执行前后以及抛出异常时执行任何操作。环绕增强的使用方法如下:

@Aspect
public class AroundAspect {
  @Around("execution(* com.example.service.*.*(..))")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    // 方法执行前的处理逻辑
    Object result = joinPoint.proceed();
    // 方法执行后的处理逻辑
    return result;
  }
}

在上面的例子中,@Around 声明了一个环绕增强,它的 pointcut 属性表示匹配 com.example.service 包下的所有方法。在处理逻辑中,使用 ProceedingJoinPoint 对象的 proceed() 方法调用目标方法,并获得方法执行结果。在方法执行前后可以编写任何需要执行的操作。如果方法抛出异常,将会继续向上抛出,由异常抛出增强来处理。

六.构造注入

构造注入是一种针对应用程序进行攻击的注入方式,旨在让攻击者可以执行恶意代码或访问敏感信息。它是通过构建特定的输入字符串来触发应用程序中的漏洞,从而实现对应用程序的控制。具体来说,构造注入是指利用应用程序的输入参数,通过构造恶意输入,使应用程序的执行逻辑发生改变,从而达到攻击的目的。常见的构造注入攻击包括 SQL 注入、命令注入、XML 注入等。

在构造注入攻击中,攻击者会构造一些特殊的输入,以欺骗应用程序,使其执行恶意代码或者访问敏感信息。攻击者可以通过构造注入攻击来窃取敏感信息,如用户名、密码、信用卡号等,并可能导致更严重的后果,如服务器崩溃、数据丢失等。为了预防构造注入攻击,开发人员应该采取安全编程实践,如使用参数化查询等方式来缓解此类安全漏洞。此外,定期进行安全测试,也是保护应用程序免受构造注入攻击的重要措施之一。

 七.使用注解的方式实现IoC

使用注解的方式实现IoC(Inversion of Control)是一种常用的Spring框架IoC实现方式。注解是Java语言的一种扩展方式,可以通过注解的方式来描述对象的属性和行为,从而实现对象的依赖注入。以下是使用注解的方式实现IoC的几个关键步骤:

  1. 标记需要注入的对象,使用注解来描述对象的属性和行为。

  2. 创建IoC容器,容器会扫描所有带有特定注解的类,将这些类实例化并装配到容器中。

  3. 定义依赖关系,通过注解来描述对象之间的依赖关系,容器会自动管理这些依赖关系,实现对象的自动装配。

例如,下面是一个使用注解方式实现IoC的示例代码:

public class UserController {

    @Autowired
    private UserService userService;

    public void addUser(User user) {
        userService.addUser(user);
    }
}

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public void addUser(User user) {
        userDao.insert(user);
    }
}

@Repository
public class UserDao {

    public void insert(User user) {
        // 插入用户数据
    }
}

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

在上述例子中,使用了@Autowired注解来标记需要注入的对象,@Service和@Repository注解用来标记服务和数据访问层的组件。@ComponentScan注解则用来告诉容器扫描哪些包下的组件进行装配。通过以上的注解配置,可以实现IoC容器对UserController、UserService和UserDao等组件的自动管理和依赖注入。

总的来说,使用注解的方式实现IoC可以减少开发人员的代码量,提高开发效率,同时也可以更加方便地管理组件之间的依赖关系。

 八.使用注解的方式实现AOP

在Java中,可以使用注解的方式来实现AOP,具体步骤如下:

  1. 定义注解

首先,需要定义一个自定义注解,用来标记需要进行AOP的方法。这个注解可以包含一些元数据,例如切点表达式等。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAopAnnotation {
    String value() default "";
}
  1. 编写切面类

接下来,需要编写切面类,这个类实现了AOP的核心逻辑,例如在方法执行前后进行日志记录、权限验证等。在切面类中使用@Before、@After等注解来表示要在方法执行前后执行的逻辑。

@Aspect
@Component
public class MyAopAspect {

    @Before("@annotation(com.example.MyAopAnnotation)")
    public void beforeAdvice() {
        System.out.println("Before advice...");
    }

    @After("@annotation(com.example.MyAopAnnotation)")
    public void afterAdvice() {
        System.out.println("After advice...");
    }
}

其中,@Aspect注解表示这个类是一个切面类,@Before、@After注解表示对应的切点逻辑。

  1. 在目标方法上添加注解

最后,在需要进行AOP的目标方法上添加自定义注解。

@MyAopAnnotation
public void doSomething() {
    // ...
}

这样,在目标方法执行前会先执行切面类中定义的@Before逻辑,然后执行目标方法,最后执行切面类中定义的@After逻辑。

以上就是使用注解的方式实现AOP的基本流程。当然,在实际应用中还需要考虑一些其他因素,例如切面类的执行顺序、异常处理等。

九.总结

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值