당연히 합격할 줄 알았다. 면접에서 뼈큐하지 않은 이상 말이다. 그리고 간단하게 자축하는 의미에서 맥주 한잔을 하였다.
분류 전체보기
- 그냥.. 2010.03.20
- Simple Factory 2010.03.18
- Factory Method 2010.03.18
- Decorator 2010.03.17
- 쉬는 3일절 2010.03.02
- 스프링 AOP(3) - Before 어드바이스 만들기 2010.01.31
- 스프링 AOP(2) 2010.01.31
- 스프링 AOP(1) 2010.01.31
그냥..
당연히 합격할 줄 알았다. 면접에서 뼈큐하지 않은 이상 말이다. 그리고 간단하게 자축하는 의미에서 맥주 한잔을 하였다.
Simple Factory
객체지향 방 굽기 느슨한 결합을 이용하여 객체지향 디자인을 만들게 된다.
수많은 if else문을 통하여 객체를 생성하게 된다. 만약 내용이 추가되거나 삭제되면 원본 클래스를 수정하므로
서브클래스 팩토리 클래스를 만들어 그쪽에서만 관리하게 만들어 준다.
SimplePizzaFactory
public class SimplePizzaFactory { public Pizza createPizza(String type){ Pizza pizza = null; if(type.equals("cheese")){ pizza = new CheesePizza(); }else if(type.equals("clam")){ pizza = new ClamPizza(); } return pizza; } }
PizzaStore
public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory){ this.factory = factory; } public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
수정삭제할 경우 SimplePizzaFactory만 수정하면 되기 때문이다. SimplePizzaFactory는 Pizza 추상클래스에 의존하고 있다.
Factory Method
Decorator
헤드퍼스트에 나온 데코리이터 설명이다.
CondimentDecorator에서 Beverage클래스를 확장하고 있다. 데코레이터 형식이 그 데코레이터로 감싸는 객체의 형식이다.
쉬는 3일절
스프링 AOP(3) - Before 어드바이스 만들기
Before 어드바이스는 스프링이 제공하는 가장 유용한 어드바이스 중 하나다. Before 어드바이스는 메서드로 넘겨주는 인자를 수정할 수 있으며 메서드를 실행하기 전에 예외를 발생시켜서 실행을 막을 수도 있다.
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import java.lang.reflect.Method;
public class SimpleBeforeAdvice implements MethodBeforeAdvice {
public static void main(String[] args) {
MessageWriter target = new MessageWriter();
// create the proxy
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new SimpleBeforeAdvice());
pf.setTarget(target);
MessageWriter proxy = (MessageWriter) pf.getProxy();
// write the messages
proxy.writeMessage();
}
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("Before method: " + method.getName());
}
}
결과
World
Before 어드바이스를 사용하여 메서드 접근 보안하기
SecureBean클래스 - 보안처리를 할 클래스
package com.lastjava.spring.ch05.security;
public class SecureBean {
public void writeSecureMessage() {
System.out.println("Every time I learn something new, "
+ "it pushes some old stuff out of my brain");
}
}
UserInfo클래스 - 사용자 정보를 저장
package com.lastjava.spring.ch05.security;
public class UserInfo {
private String username;
private String password;
public UserInfo(String username, String password) {
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
}
SecurityManager클래스 - 사용자 인증을 담당하고 그들의 계정 정보를 담아뒸더가 나중에 참조
package com.lastjava.spring.ch05.security;
public class SecurityManager {
private static ThreadLocal<UserInfo> threadLocal = new ThreadLocal<UserInfo>();
public void login(String username, String password) {
// assumes that all credentials
// are valid for a login
threadLocal.set(new UserInfo(username, password));
}
public void logout() {
threadLocal.set(null);
}
public UserInfo getLoggedOnUser() {
return threadLocal.get();
}
}
SecurityAdvice클래스 - 해당 메서드 접근전에 실행 메서드실행을 예외처리로 방지한다.
package com.lastjava.spring.ch05.security;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class SecurityAdvice implements MethodBeforeAdvice {
private SecurityManager securityManager;
public SecurityAdvice() {
this.securityManager = new SecurityManager();
}
public void before(Method method, Object[] args, Object target)
throws Throwable {
UserInfo user = securityManager.getLoggedOnUser();
if (user == null) {
System.out.println("No user authenticated");
throw new SecurityException(
"You must login before attempting to invoke the method: "
+ method.getName());
} else if ("janm".equals(user.getUsername())) {
System.out.println("Logged in user is janm - OKAY!");
} else {
System.out.println("Logged in user is " + user.getUsername()
+ " NOT GOOD :(");
throw new SecurityException("User " + user.getUsername()
+ " is not allowed access to method " + method.getName());
}
}
}
SecurityExample 클래스
package com.lastjava.spring.ch05.security;
import org.springframework.aop.framework.ProxyFactory;
public class SecurityExample {
public static void main(String[] args) {
// get the security manager
SecurityManager mgr = new SecurityManager();
// get the bean
SecureBean bean = getSecureBean();
// try as robh
mgr.login("janm", "*****");
bean.writeSecureMessage();
mgr.logout();
// try as janm
try {
mgr.login("mallory", "****");
bean.writeSecureMessage();
} catch(SecurityException ex) {
System.out.println("Exception Caught: " + ex.getMessage());
} finally {
mgr.logout();
}
// try with no credentials
try {
bean.writeSecureMessage();
} catch(SecurityException ex) {
System.out.println("Exception Caught: " + ex.getMessage());
}
}
private static SecureBean getSecureBean() {
// create the target
SecureBean target = new SecureBean();
// create the advice
SecurityAdvice advice = new SecurityAdvice();
// get the proxy
ProxyFactory factory = new ProxyFactory();
factory.setTarget(target);
factory.addAdvice(advice);
return (SecureBean)factory.getProxy();
}
}
결과
Every time I learn something new, it pushes some old stuff out of my brain
Logged in user is mallory NOT GOOD :(
Exception Caught: User mallory is not allowed access to method writeSecureMessage
No user authenticated
Exception Caught: You must login before attempting to invoke the method: writeSecureMessage
스프링 AOP(2)
스프링 AOP의 핵심 아키텍처는 프록시를 기반으로 하고 있다. 어드바이스가 적용된 클래스의 객체를 생성하고 싶다면, 먼저 프록시의 위빙할 모든 액스팩트를 ProxyFactory에 제공하고 반드시 ProxyFactory클래스를 사용하여 해당 클래스 인스턴스의 폭시를 만들어야 한다. 내부적으로 스프링은 두 개의 프록시 구현체가 있다. JDK동적 프록시와 CGLIB프록시다.
스프링 조인포인트
스프링 AOP에서 주목해야 할 것 하나는 오직 한 종류의 조인포인트인 메서드 호출 조인포인트만 지원한다는 것이다. 이런 단순함이 스프링의 접근성을 높여준다.
스프링 애스팩트
스프링 AOP에서 에스팩트는 Advisor 인터페이스를 구현한 클래스의 인스턴스를 말한다. Advisor는 두 개의 하위 인터페이스 IntroductionAdvisor와 PointcutAdvisor가 있다. PointcutAdvisor인터페이스는 포인트컷을 사용하는 모든 어드바이저들이 구현하고 있다. 이것을 사용하여 해당 조인포인트에 어드바이스의 기능을 적용한다.
ProxyFactory 클래스
ProxyFactory 클래스는 스프링 AOP에서 프록시 생성과 위빙을 제어한다.
어드바이스이름 | 인터페이스 | 설명 |
Before | org.springframework.aop. MethodBeforeAdivce |
Before 어드바이스를 사용하여, 조인포인트를 실행가히 전에 어떤 처리를 할 수 있다. 스프링에서 조인포인트는 항상 메서드 호출이기 때문에 해당 메서드를 처리하기 전에 전처리 과정을 수행하는 데 사용할 수 있다. Before 어드바이스는 호출하는 메서드에 넘겨주는 인자들을 비롯한 타켓 객체에도 접근할 수 있지만 메서드 실행 자체를 제어할 수는 없다. |
After Returning | org.springframework.aop. AfterReturningAdvice |
After Returning 어드바이스는 조인포인트에 있는 메서드가 실행을 끝내고 값을 반환 했을 때 실행된다. After Returning 어드바이스는 해당 메서드에 넘겨주는 인자 타켓 객체 그리고 반환값에 접근 할 수 있다. After Returning 어드바이스를 적용하기 전에 이미 메서드는 실행을 마쳤기 때문에 메서드 호출 자체를 제어할 수는 없다. |
Around | org.aopalliance.intercept. MethodInterceptor |
스프링에서 Around 어드바이스는 AOP연합 표준 MethodInterceptor를 사용하도록 만들었다. 여러분이 만든 어드바이스는 메서드 실행전과 후에 어떤 작업을 수행할 수 있으며, 어느 시점에 메서드를 실행하지 않을지 제어할 수 있다. 원한다면 해당 메서드 대신에 별도의 로직을 만들어 사용할 수 있다. |
Throws | org.springframework.aop. ThrowsAdvice |
Throws 어드바이스는 메서드가 호출된 후에 실행되는데 단 해당 메서드가 예외를 던졌을 경우에만 실행한다. 원하면 특정 예외만 잡아내도록 설정할 수 있으며, 해당 예외를 발생시킨 메서드에 넘겨준 인자와 타켓 객체에 접근할 수 있다. |
Introduction | org.springframework.aop. IntroductionInterceptor |
스프링은 인트로덕션을 특별한 인터셉터 종류로 모델링했다. 인트로덕션 인터셉터를 사용하여, 여러분은 어드바이스를 적용할 메서드 구현체를 지정할 수 있다. |
스프링 AOP(1)
AOP 개념
조인포인트(joinpoint) : 애플리케이션 중의 특별한 지점 메서드 호출, 메서드 실행자체, 클래스 초기화, 객체성생
어드바이스(advice) : 조인 포인트에 실행되는 코드
포인트컷(pointcuts) : 조인 포인트의 집합체 어드바이스 실행을 정의
애스팩트(aspect) : 어드바이스와 포인트의 조합
위빙(weaving) : 애스펙트를 주입하는 과정
타켓(target) : 자신의 실행 흐름이 어떠한 aop처리로 인해 수정되는 객체
인트로덕션(introduction) : 객체구조를 수정하여 새로운 메서드나 그 필드를 추가할 수 있는 처리
AOP를 이용한 "Hello, World"
MessageWriter 클래스
public class MessageWriter {
public void writeMessage(){
System.out.print("World");
}
}
MessageDecorator 클래스
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageDecorator implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.print("Hello ");
Object retVal = invocation.proceed();
System.out.println("!");
return retVal;
}
}
MessageDecorator 클래스
import org.springframework.aop.framework.ProxyFactory;
public class HelloWorldWeaver {
public static void main(String[] args){
MessageWriter target = new MessageWriter();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MessageDecorator());
pf.setTarget(target);
MessageWriter proxy = (MessageWriter) pf.getProxy();
target.writeMessage();
System.out.println("");
proxy.writeMessage();
}
}
결과물
Hello World!