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