JAVA_HOME、CLASSPATH、Pathspring.jar、commons-logging-1.0.4.jar
public interface ServiceBean {
void addUser(String username, String password);
void deleteUser(String username);
boolean findUser(String username);
String getPassword(String username);
}
public class MyServiceBean implements ServiceBean {
private Map map = new HashMap<>();
public void setUserDir(String dir) { this.dir = dir; }
public void addUser(String username, String password) {
if (!map.containsKey(username)) map.put(username, password);
else throw new RuntimeException("User already exist.");
}
public void deleteUser(String username) {
if (map.remove(username) == null) throw new RuntimeException("User not exist.");
}
public boolean findUser(String username) { return map.containsKey(username); }
public String getPassword(String username) { return map.get(username); }
}
public class Main {
public static void main(String[] args) {
ServiceBean service = new MyServiceBean();
service.addUser("bill", "hello");
service.addUser("tom", "goodbye");
service.addUser("tracy", "morning");
System.out.println("tom's password: " + service.getPassword("tom"));
if (service.findUser("tom")) service.deleteUser("tom");
}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" />
</beans>
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
ServiceBean service = (ServiceBean) factory.getBean("service");
// 業務操作...
factory.destroySingletons();

public class LogAdvisor implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) {
System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");
}
}
<bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
<bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
<bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
<property name="target"><ref local="serviceTarget"/></property>
<property name="interceptorNames">
<list><value>logAdvisor</value></list>
</property>
</bean>


public class PasswordAdvisor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
Object ret = invocation.proceed();
if (ret == null) return null;
String password = (String) ret;
return new String(new char[password.length()]).replace('\0', '*');
}
}
<bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" />
<bean id="passwordAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice"><ref local="passwordAdvisorTarget"/></property>
<property name="patterns"><list><value>.*getPassword</value></list></property>
</bean>

public class ExceptionAdvisor implements ThrowsAdvice {
public void afterThrowing(RuntimeException re) {
System.out.println("[Exception] " + re.getMessage());
}
}

Spring IoC 容器管理對象生命週期,AOP 動態增強業務方法且不影響介面。核心原則:面向介面編程,利用 Java 動態代理實現鬆耦合擴展。