728x90

들어가면서.

Aspect-Oriented Programming (AOP) 란?

Spring의 AOP는 다양한 애플리케이션에서 공통적으로 발생하는 문제들을 해결하기 위해 사용됩니다. AOP는 메소드 호출 전후에 수행되는 작업(어드바이스)과 해당 메소드를 정의한 포인트컷(Pointcut)을 조합하여 프로그램의 여러 부분에서 재사용할 수 있는 기능을 제공합니다.

Spring 프레임워크에서 AOP가 사용되는 대표적인 기능은 다음과 같습니다.

  • 트랜잭션 관리

Spring의 트랜잭션 관리 기능은 AOP를 기반으로 구현되어 있습니다. 스프링에서는 @Transactional 어노테이션을 사용하여 트랜잭션을 관리하며, 이 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

  • 보안 처리

Spring Security는 스프링에서 제공하는 보안 처리 모듈로서, AOP를 사용하여 보안 기능을 구현합니다. 스프링 시큐리티에서는 @PreAuthorize@PostAuthorize 어노테이션을 사용하여 메소드의 호출 전과 후에 보안 검사를 수행하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

  • 캐싱 처리

Spring은 AOP를 이용하여 캐싱 처리 기능을 제공합니다. 스프링에서는 @Cacheable, @CachePut, @CacheEvict 등의 어노테이션을 사용하여 메소드의 결과를 캐싱하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

  • 로깅 처리

Spring에서는 AOP를 이용하여 로깅 처리 기능을 제공합니다. 스프링에서는 @Around 어노테이션을 사용하여 메소드의 실행 전과 후에 로깅 처리를 수행하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

  • 예외 처리

Spring에서는 AOP를 이용하여 예외 처리 기능을 제공합니다. 스프링에서는 @AfterThrowing 어노테이션을 사용하여 메소드에서 예외가 발생했을 때 처리할 로직을 구현하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

  • 성능 모니터링

Spring에서는 AOP를 이용하여 성능 모니터링 기능을 제공합니다. 스프링에서는 @Around 어노테이션을 사용하여 메소드의 실행 시간을 측정하며, 이러한 어노테이션은 내부적으로 AOP를 이용하여 구현됩니다.

다음은 Spring AOP를 사용하여 메서드 실행 시간을 로깅하는 간단한 예제 코드입니다.

  1. LoggingAspect 클래스 정의
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Pointcut("execution(* com.example.service.*.*(..))")
	public void serviceMethods() {}
	
	@Before("serviceMethods()")
	public void logMethodStart() {
	    logger.info("Method execution started");
	}
	
	@After("serviceMethods()")
	public void logMethodEnd() {
	    logger.info("Method execution ended");
	}
}
  1. Service 클래스 정의
import org.springframework.stereotype.Service;

@Service
public class MyService {
    
    public void doSomething() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("Doing something...");
    }
}
  1. Main 클래스 정의
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    
    public static void main(String[] args) throws InterruptedException {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyService service = context.getBean(MyService.class);
        service.doSomething();
    }
}
  1. AppConfig 클래스 정의
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

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

위 코드에서, LoggingAspect 클래스는 AOP 관련 어노테이션(@Aspect, @Before, @After, @Pointcut)을 사용하여 메서드 실행 시간을 로깅합니다. Service 클래스는 AOP를 적용받을 대상이 되는 비즈니스 로직을 구현합니다. Main 클래스는 ApplicationContext를 생성하고 Service 클래스를 불러와서 메서드를 실행합니다. AppConfig 클래스는 ApplicationContext를 생성하고, AOP를 사용하기 위해 @EnableAspectJAutoProxy 어노테이션을 사용합니다.

실행 결과는 다음과 같습니다.

Method execution started
Doing something...
Method execution ended

즉, LoggingAspect 클래스의 logMethodStart 메서드가 MyService 클래스의 doSomething 메서드 실행 전에, logMethodEnd 메서드가 실행 후에 호출되어 메서드 실행 시간을 로깅하는 것을 확인할 수 있습니다.


내저장소 바로가기 luxury515

'Springboot3.0 > 핵심기능' 카테고리의 다른 글

Spring의 핵심요소  (0) 2023.04.15
Spring IoC 에 관하여.  (0) 2023.04.15
Spring Security 와 Siro 에 대한 비교  (0) 2023.04.15
Redis를 이용한 refresh token  (0) 2023.04.11
Redis를 이용한 중복요청 방지  (0) 2023.04.11
728x90

Spring 프레임워크의 핵심 기술에는 다음과 같은 것들이 있습니다.

  1. Inversion of Control (IoC)

Spring의 IoC는 객체 생성, 관리, 의존성 주입 등의 작업을 자동으로 수행하여 개발자가 비즈니스 로직에 집중할 수 있도록 합니다. 스프링에서는 빈(Bean)이라는 개념을 도입하여 객체를 생성하고 관리합니다.

  1. Aspect-Oriented Programming (AOP)

Spring의 AOP는 다양한 애플리케이션에서 공통적으로 발생하는 문제들을 해결하기 위해 사용됩니다. AOP는 메소드 호출 전후에 수행되는 작업(어드바이스)과 해당 메소드를 정의한 포인트컷(Pointcut)을 조합하여 프로그램의 여러 부분에서 재사용할 수 있는 기능을 제공합니다.

  1. Spring MVC

Spring MVC는 Model-View-Controller 아키텍처 패턴을 기반으로 한 웹 애플리케이션 개발을 위한 프레임워크입니다. 스프링 MVC는 각 요청에 대한 처리를 컨트롤러(Controller)에서 담당하며, 모델(Model)과 뷰(View)를 분리하여 개발의 유연성을 높여줍니다.

  1. Spring Data

Spring Data는 다양한 데이터베이스를 쉽게 다룰 수 있는 기술을 제공합니다. Spring Data는 JPA, MongoDB, Redis 등의 데이터베이스에 대한 지원을 제공합니다.

  1. Spring Security

Spring Security는 웹 애플리케이션의 보안을 담당하는 프레임워크입니다. 스프링 시큐리티는 인증(Authentication)과 권한 부여(Authorization)를 처리하며, 보안에 관련된 다양한 기능을 제공합니다.

  1. Spring Integration

Spring Integration은 다양한 시스템 간의 메시지 통합을 위한 프레임워크입니다. 스프링 인티그레이션은 다양한 프로토콜을 지원하며, 여러 시스템 간의 데이터 통합을 용이하게 해줍니다.


내저장소 바로가기 luxury515

'Springboot3.0 > 핵심기능' 카테고리의 다른 글

Spring AOP에 관련하여.  (0) 2023.04.15
Spring IoC 에 관하여.  (0) 2023.04.15
Spring Security 와 Siro 에 대한 비교  (0) 2023.04.15
Redis를 이용한 refresh token  (0) 2023.04.11
Redis를 이용한 중복요청 방지  (0) 2023.04.11
728x90

들어가면서

IoC(Inversion of Control, 제어의 역전)는 객체 지향 프로그래밍에서 객체 생성과 의존성 관리 등을 개발자가 직접 제어하는 것이 아니라 프레임워크나 컨테이너가 제어하는 것을 말합니다.

Spring 프레임워크에서의 IoC는 객체의 생성과 소멸, 의존성 주입 등을 Spring 컨테이너가 제어하도록 합니다. 이를 통해 객체간의 결합도를 낮출 수 있고, 유연하고 확장 가능한 코드를 작성할 수 있습니다.

IoC종류 뭐가 있을까?

Spring Framework에서는 다음과 같은 종류의 IOC(Inversion of Control) 컨테이너가 있습니다.

  1. BeanFactory
  1. ApplicationContext
  1. WebApplicationContext
  • BeanFactory는 가장 기본적인 IOC 컨테이너로서, Bean 객체의 생성, 관리, 제공에 대한 기능을 제공합니다.
  • ApplicationContext는 BeanFactory를 상속받아 기능을 보완한 것으로서, AOP, 메시지 처리 등 다양한 기능을 지원합니다.
  • WebApplicationContext는 웹 어플리케이션에서 사용하는 IOC 컨테이너로서, HTTP 요청에 대한 처리와 관련된 Bean 객체를 관리합니다.

여러가지 설정방법

Spring Framework에서는 다양한 환경에서 사용할 수 있는 다양한 IOC 컨테이너를 제공합니다. 예를 들어, XML, 어노테이션, 자바 설정 파일 등을 이용해서 Bean 객체를 등록하고 관리하는 방법을 지원합니다. 이러한 다양한 방법을 통해 유연하게 IOC 컨테이너를 사용할 수 있습니다.

아래는 Spring IoC를 사용한 간단한 코드입니다.

public interface UserService {
    void addUser(User user);
}

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

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

public interface UserDao {
    void addUser(User user);
}

public class UserDaoImpl implements UserDao {
    public void addUser(User user) {
        // user를 DB에 저장하는 코드
    }
}

위 코드에서 UserServiceImpl 클래스는 UserDao 클래스에 의존하고 있습니다. 하지만 IoC를 사용하면 UserDao 클래스를 생성하고 UserServiceImpl 객체에 주입하는 작업을 Spring 컨테이너가 대신합니다.

<bean id="userDao" class="com.example.UserDaoImpl" />
<bean id="userService" class="com.example.UserServiceImpl">
    <property name="userDao" ref="userDao" />
</bean>

위 XML 설정 파일에서 UserDaoImpl 클래스를 userDao 빈으로 등록하고, UserServiceImpl 클래스를 userService 빈으로 등록하면 Spring 컨테이너는 userDao 빈을 생성한 후에 userService 빈을 생성하면서 userDao 빈을 주입합니다.

어떤 장단은 뭐가 있을까?

IoC를 사용하면 객체 생성과 의존성 관리를 Spring 프레임워크가 대신 처리하기 때문에 개발자는 객체 생성과 관련된 코드를 작성하지 않아도 되고, 객체간의 결합도가 낮아져 유연하고 확장 가능한 코드를 작성할 수 있습니다.

Spring 프레임워크에서 IoC는 DI(Dependency Injection, 의존성 주입)라는 방식으로 구현됩니다. DI는 객체간의 의존성을 외부에서 주입하는 방식으로, 객체간의 결합도를 낮출 수 있습니다. Spring 컨테이너는 DI를 사용하여 객체를 생성하고 의존성을 주입합니다.

따라서, Spring 프레임워크에서 IoC를 사용하면 유연하고 확장 가능한 코드를 작성할 수 있으며, 객체간의 결합도를 낮출 수 있습니다.


내저장소 바로가기 luxury515

'Springboot3.0 > 핵심기능' 카테고리의 다른 글

Spring AOP에 관련하여.  (0) 2023.04.15
Spring의 핵심요소  (0) 2023.04.15
Spring Security 와 Siro 에 대한 비교  (0) 2023.04.15
Redis를 이용한 refresh token  (0) 2023.04.11
Redis를 이용한 중복요청 방지  (0) 2023.04.11
728x90

Introduction

Spring Security는 애플리케이션 보안에 대한 표준 기능을 제공하는 프레임워크입니다. 최근 Spring Security 5.7 버전이 출시되면서 이전 버전과 다른 점이 몇 가지 있다는 것을 알아보겠습니다. 또한, Spring Security와 Siro의 차이점과 기능 및 성능 비교에 대해서도 알아볼 것입니다.

Spring Security와 Siro 차이점 및 기능, 성능 비교

Spring Security와 Siro는 모두 보안 프레임워크입니다. 그러나 두 프레임워크는 목적이 다릅니다. Spring Security는 다양한 인증 및 권한 부여 방식을 제공하며, Siro는 주로 RBAC(Role-Based Access Control)를 지원합니다. 또한, Spring Security는 많은 기능을 제공하며, 설정이 복잡할 수 있습니다. 반면, Siro는 간단한 설정으로 사용할 수 있지만, 기능이 제한될 수 있습니다. 성능 측면에서도 Spring Security가 더 우수합니다.

다음은 Spring Security와 Siro의 기능 및 성능을 비교한 표입니다.

Spring SecuritySiro
인증 방식다양한 인증 방식 제공기본적으로 Form 인증
권한 부여 방식다양한 권한 부여 방식 제공주로 RBAC 지원
설정의 복잡성높음낮음
기능많음제한적
성능우수보통

Spring Security 5.7 이후 버전 설정 방법 및 예시 코드

다음은 Spring Security 5.7 이전 버전에서 JWT 인증을 사용하는 방법의 예시 코드입니다.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtTokenFilter jwtTokenFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .and()
            .addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService());
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        return daoAuthenticationProvider;
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
            User.builder()
                .username("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER")
                .build()
        );
    }
}

5.7 이후 버전 아래 형식으로 바뀜

참고: https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
        return http.build();
    }
		@Bean
		    public WebSecurityCustomizer webSecurityCustomizer() {
		        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
		    }

}

Postman으로 JWT 토큰 발급 과정 구체적인 코드 작성

Postman을 사용하여 JWT 토큰 발급을 구현하기 위해서는 먼저 Spring Security 설정에서 JWT 인증을 사용해야 합니다. JWT 토큰을 생성하고 발급하는 방법은 다음과 같습니다.

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {

    Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                    loginRequest.getUsername(),
                    loginRequest.getPassword()
            )
    );

    SecurityContextHolder.getContext().setAuthentication(authentication);

    String jwt = tokenProvider.generateToken(authentication);
    return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}

MySQL DB 설정과 application.yml 파일 설정

Spring Boot에서는 application.yml 또는 application.properties 파일을 사용하여 애플리케이션 설정을 관리합니다. MySQL DB를 사용하는 경우, application.yml 파일은 다음과 같이 설정할 수 있습니다.

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dbName
    username: dbUser
    password: dbPassword
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

ORM으로 JPA 사용하기

Spring Boot에서는 JPA를 사용하여 ORM(Object-Relational Mapping)을 구현할 수 있습니다. JPA는 Java Persistence API의 약자로, 객체와 관계형 데이터베이스 간의 매핑을 처리합니다. JPA를 사용하는 경우, 다음과 같이 의존성을 추가하고, Entity 클래스를 작성하고, Repository 인터페이스를 작성하면 됩니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    // getters and setters
}

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

Conclusion

Spring Security 5.7 이후 버전에서는 여러 개선 사항이 추가되어 있습니다. 또한, Spring Security와 Siro의 차이점과 기능 및 성능 비교를 통해 각각의 장단점을 알아봤습니다. JWT 토큰 발급 과정과 MySQL DB 설정, JPA 사용 방법에 대해서도 자세히 알아보았습니다. 이를 토대로 Spring Security를 보다 효율적으로 사용할 수 있을 것입니다.


내저장소 바로가기 luxury515

'Springboot3.0 > 핵심기능' 카테고리의 다른 글

Spring의 핵심요소  (0) 2023.04.15
Spring IoC 에 관하여.  (0) 2023.04.15
Redis를 이용한 refresh token  (0) 2023.04.11
Redis를 이용한 중복요청 방지  (0) 2023.04.11
Springboot3.0 에서 kafka적용해보기  (0) 2023.04.11

+ Recent posts