공부를 해야하는데 너무 게으르다. 위에선 열심히 던져놓고 결과를 원하니 답답할 뿐이다. 너무 쉽게 사는거 아닌지 내가 아니면 할 사람도 없으면서 글세다 기원이집에서 자주 지내고 있다. 최근에 기원이가 좋은 회사에 서류전형에 붙어서 너무 기뻤다.
당연히 합격할 줄 알았다. 면접에서 뼈큐하지 않은 이상 말이다. 그리고 간단하게 자축하는 의미에서 맥주 한잔을 하였다. 
 그런데 이게 웬일 면접보고 상황이 안 좋아진 모양이다. 정말 가고 싶어 하던 회사였는데.. 안타까울 따름이다. 나 나름대로 생각은 기원이가 안정적인 회사에 들어가서 나랑 공부를 열심히하고 도움도 되고 그런 걸 원했지만 다 뜻대로는 안되는 모양이다. 나로써는 그런 회사에서는 정말 우수하고 뛰어난 사람들만 가는 줄만 알고 있다. 그러나 무엇가 보여준듯 기원이가 기특했고 나도 노력을 해야 겠다는 생각이 들었다. 상황이 안 좋은데 뭐라 위로 해줘야 할지 모르겠다. 그냥 전화로 덤덤하게 받아들여 별 일 아니라고 생각하게 만들고 싶었다. 아직 어리니까 기회는 더 있을 듯하다. 
 나도 올해 안에는 때려 쳐야 하는데 고민이 많다. 그냥 자유롭게 살고 싶다. 세창씨가 일을 같이 하자고 했는데 귀가 완전 팔랑팔랑 거렸다. 그 사람이라면.. 생각과 함께 말이다. 라스트자바도 해야되는데 열심히 하자고 사람들 다독여 놓고 내가 열심히 안하고 있다. 한심하네.. 
 다음주에는 게시판에 온통 신경을 집중해야 겠다. 에러를 너무 잘 내니 신중해서 봐야겠다. 너무 놀아서 문제다 요즘은 정말 어디에도 집중할 수가 없다.  

객체지향 방 굽기 느슨한 결합을 이용하여 객체지향 디자인을 만들게 된다.

수많은 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;
	}
}
PizzaStore에서 SimplePizzaFactory를 통해서 만들도록 세부화 한 것이다. PizzaStore에 원래 포함되어도 되는 코드이지만
수정삭제할 경우 SimplePizzaFactory만 수정하면 되기 때문이다. SimplePizzaFactory는 Pizza 추상클래스에 의존하고 있다.
 



팩토리 메서드 패턴 - 팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만듭니다. 팩토리 메소드 패턴를 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에서 맡기는 것이다.



객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.


헤드퍼스트에 나온 데코리이터 설명이다.
CondimentDecorator에서 Beverage클래스를 확장하고 있다. 데코레이터 형식이 그 데코레이터로 감싸는 객체의 형식이다.
 어제 운동을 좀 했더니.. 몸 상태가 완전 녹초 상태였다. 오늘도 나가놀까나 봤는데 비오고 눈오고.. 왠 눈이야 그래서 걍 집에서 스트럿츠2 책을 봤다. 금방 볼 것 같은 느낌이였지만 딴 짓한다고 다 보지는 못했다 스프링보다 편할까? 괜히 공부하나.. 이런저런 생각.. 스트럿츠 태그라이브러리가 작동을 안해서 티비를 보니 엽문을 케이블에서 해주었다. 뭐 내용은 그닥 근데 액숀신이 완전 쩔어~~ 10대1  소나기 주먹 맥주와 치킨을 먹으러 정신없이 봤는데 볼만한 영화였다고 할까나?? 내일 또 출근이구나 어서 월급날이 되었으면... 쩝 사고 싶은 책이 너무 많다. 스트럿츠2 책을 다시 사야할 것 같은 느낌 왜 사는 책마다 개 쓰레기인지.. 쩝 이번주 안에 스트럿츠2 완료하고 게시판이나 만들어서 올려야 겠다. 

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());
    }

}

결과

Before method : writeMessage
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();

    }
}

결과

Logged in user is janm - OKAY!
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 아키텍처
 스프링 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 개념

조인포인트(joinpoint) : 애플리케이션 중의 특별한 지점 메서드 호출, 메서드 실행자체, 클래스 초기화, 객체성생

어드바이스(advice) : 조인 포인트에 실행되는 코드

포인트컷(pointcuts) : 조인 포인트의 집합체 어드바이스 실행을 정의

애스팩트(aspect) : 어드바이스와 포인트의 조합

위빙(weaving) : 애스펙트를 주입하는 과정

타켓(target) : 자신의 실행 흐름이 어떠한 aop처리로 인해 수정되는 객체

인트로덕션(introduction) : 객체구조를 수정하여 새로운 메서드나 그 필드를 추가할 수 있는 처리

AOP를 이용한 "Hello, World"

MessageWriter 클래스

package com.lastjava.spring.ch05.simple;

public class MessageWriter {
 public void writeMessage(){
  System.out.print("World");
 }
}

MessageDecorator 클래스

package com.lastjava.spring.ch05.simple;

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 클래스

package com.lastjava.spring.ch05.simple;

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();
 }
}

결과물

World
Hello World!

+ Recent posts