목록Backend/Toby Spring (22)
elevne's Study Note
Spring 에서 Application Context 는 그 자체로 IoC, DI 를 위한 빈 팩토리이면서 그 이상의 기능을 지니기도 한다. 스프링의 빈 팩토리와 애플리케이션 컨텍스트는 각각 기능을 대표하는 BeanFactory 와 ApplicationContext 라는 두 개의 인터페이스로 정의되어 있다. ApplicationContext 는 BeanFactory 인터페이스를 상속한 서브 인터페이스이다. 스프링 애플리케이션은 최소한 하나 이상의 IoC 컨테이너, 즉 애플리케이션 컨텍스트 오브젝트를 갖는다. 가장 간단하게 IoC 컨테이너를 만드는 방법은 ApplicationContext 구현 클래스의 인스턴스를 만드는 것이다. StaticApplicationContext applicationContext..
이번에는 Spring 에서 자주 사용되는 편리한 애노테이션들에 대해 알아볼 수 있었다. @Resource @Configuration 을 사용하는 클래스 내에서 @Resource 애노테이션을 사용하기도 한다. 이는 @Autowired 와 비슷하게 필드에 빈을 주입받을 때 사용하는데, 차이점으로 @Autowired 는 필드의 타입을 기준으로 빈을 찾고 @Resource 는 필드 이름을 기준으로 빈을 찾는다. @Resource Database embeddedDatabase; @EnableTransactionManagement 이전 시간에도 알아보았듯이 @EnableTransactionManagement 를 사용하여 트랜잭션 AOP 를 활성화시켜줄 수 있다. 만약 이를 달아주지 않는다면 다음 네 가지 클래스를 ..
DefaultAdvisorAutoProxyCreator 는 등록된 빈 중에서 Advisor 인터페이스를 구현한 것을 모두 찾고, 생성되는 모든 빈에 대해 Advisor 의 Pointcut 을 적용하며 프록시 적용 대상을 선정한다. 빈 클래스가 프록시 선정 대상이라면, 프록시를 만들어서 원래 빈 오브젝트와 바꾼다. 기존의 transactionAdvice, Advisor 을 수정할 필요 없이, DefaultAdvisorAutoProxyCreator 을 빈에 등록해주기만 하면 된다고 한다. 아래와 같이 빈을 등록한다. @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { return new DefaultAdvisorAuto..
자바에서는 JDK 에서 제공하는 다이나믹 프록시 외에도 편리하게 프록시를 만들 수 있는 다양한 기술이 존재한다. 그 중 하나는 ProxyFactoryBean 이다. 이는 프록시를 생성해서 빈 오브젝트로 등록하게 해준다. 기존에 작성했던 TxProxyFactoryBean 과 달리 ProxyFactoryBean 은 순수하게 프록시를 생성하는 작업만을 담당하고 프록시를 통해 제공해줄 부가기능은 별도의 빈에 둘 수 있다. ProxyFactoryBean 이 생성하는 프록시에서 사용할 부가기능은 MethodInterceptor 인터페이스를 구현해서 만든다. 이전에 사용한 InvocationHandler 은 타깃에 대한 정보를 알아야했지만, MethodInterceptor 은 ProxyFactoryBean 으로부터 ..
이전까지 작업한 TransactionHandler, 다이나믹 프록시를 스프링의 DI 를 통해 사용할 수 있어야 할 것이다. 하지만 DI 의 대상이 되는 다이나믹 프록시 오브젝트는 일반적인 스프링의 빈으로는 등록할 방법이 없다. 스프링은 내부적으로 리플렉션 API 를 사용하여 빈 정의에 나오는 클래스 이름을 가지고 오브젝트를 생성한다. 하지만 다이나믹 프록시 오브젝트는 이런 식으로 프록시 오브젝트가 생성되지 않는다. (어떤 클래스를 구체적으로 사용하는지도 알 수 없다) 다이나믹 프록시를 사용하게 되면 프록시 오브젝트 클래스 정보를 미리 알아내서 스프링 빈에 정의할 방법이 없다는 뜻이다. 다이나믹 프록시는 Proxy 클래스의 newProxyInstance() 메소드를 통해서만 생성할 수 있다. 이 때, Fa..
이전 시간에는 트랜잭션 기능, 즉 비즈니스 로직과 직접적으로 연관이 없는 코드를 서비스 밖으로 빼주는 작업을 진행해주려 하였다. 부가기능 전부를 UserServiceTx 라는, UserService 인터페이스를 구현한 클래스로 옮겨두고 UserServiceImpl 에서는 트랜잭션과 관련된 기능을 전부 제거해줄 수 있었다. 이 때, 부가기능은 마친 해당 클래스가 핵심 기능을 가진 클래스인 것처럼 꾸며서, 클라이언트가 해당 클래스를 거쳐 핵심 기능을 사용하도록 만들어져야 한다. (이를 위해 UserServiceTx 또한 UserService 인터페이스를 구현하도록 만든 것) 이와 같이 자신이 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장하여 클라이언트의 요청을 받아주는 것을 프록시 (Proxy) 라고..
AOP 는 IoC/DI, 서비스 추상화와 더불어서 Spring 의 3 대 기반 기술 중 하나이다. 스프링에 적용된 AOP 의 적용 대상은 선언적 트랜잭션 기능이다. 서비스 추상화를 통해 많은 근본적인 문제를 해결했던 트랜잭션 경계설정 기능을 AOP 를 이용하여 더욱 깔끔하게 작성해볼 수 있다. 이전까지 작성한 UserService 는 스프링이 제공하는 트랜잭션 인터페이스를 사용했지만 비즈니스 로직이 주인이어야 할 때에도 메소드 내에는 트랜잭션 코드가 더욱 많은 자리를 차지하고 있다. 트랜잭션 경계설정 코드와 비즈니스 로직 코드 간에는 서로 주고받는 정보도 없다. 이럴 때, 트랜잭션 코드를 간단하게 클래스 밖으로 뽑아내 버릴 수 있다. UserService 클래스를 다른 클래스에서 참조하여 사용할 수 있게..
기존에 작성한 UserService 에 새로운 기능을 추가한다. 고객의 레벨이 업그레이드 될 때 해당 사용자에게 업그레이드 안내 메일을 보내는 것이다. 유저의 레벨을 업그레이드하는 upgradeLevel() 메서드 끝에 새로 만드는 메일을 보내는 메서드를 추가해주면 될 것이다. private MailSender mailSender; public void sendUpgradeEmail(User user) { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setTo(user.getEmail()); mailMessage.setFrom("useradmin@ksug.org"); mailMessage.setSubject("UPGRADE 안..