I can not understand how it works at all. I use ThreadLocal<> . A simple example:

Secure bean

 public class SecureBean { public void writeSecureMessage() { System.out.println("Test"); } } 

UserInfo.java

 public class UserInfo { private String name; private String password; /* Геттеры и сеттеры */ } 

SimpleSecurityManager

 public class SimpleSecurityManager implements SecurityManager { private static ThreadLocal<UserInfo> threadLocal = new ThreadLocal<>(); public void login(String userName, String userPassword) { threadLocal.set(new UserInfo(userName, userPassword)); } public void logout() { threadLocal.set(null); } public UserInfo getLoggedOnUser() { return threadLocal.get(); } } 

SecurityAdvise.java

 public class SecurityAdvise implements MethodBeforeAdvice { private SecurityManager securityManager; @Override public void before(Method method, Object[] objects, Object o) throws Throwable { UserInfo user = securityManager.getLoggedOnUser(); if (user == null) { System.out.println("No user auth"); throw new SecurityException( "You must be logged to attempt to invoke this method: " + method.getName() ); } else if ("admin".equals(user.getName())) { System.out.println("Logged user is admin - OK!"); } else { System.out.println("Bad user!"); throw new SecurityException( "You must be logged to attempt to invoke this method: " + method.getName() ); } } public void setSecurityManager(SecurityManager securityManager) { this.securityManager = securityManager; } } 

AppConfig.java

 @Configuration public class AppConfig { @Bean("securityManager") public SecurityManager securityManager() { return new SimpleSecurityManager(); } @Bean("securityAdvise") public SecurityAdvise securityAdvise() { SecurityAdvise advise = new SecurityAdvise(); advise.setSecurityManager(securityManager()); return advise; } @Bean("secureBean") public SecureBean secureBean() { SecureBean target = new SecureBean(); SecurityAdvise advise = securityAdvise(); ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTarget(target); proxyFactory.addAdvice(advise); return (SecureBean) proxyFactory.getProxy(); } } 

Application.java (Works)

 public class Application { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); SecureBean secureBean = (SecureBean) context.getBean("secureBean"); SecurityManager securityManager = (SecurityManager) context.getBean("securityManager"); securityManager.login("admin", "pass"); secureBean.writeSecureMessage(); securityManager.logout(); } } 

Application.java (Still works)

 public class Application { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); SecureBean secureBean = (SecureBean) context.getBean("secureBean"); SecurityManager securityManager = (SecurityManager) context.getBean("securityManager"); securityManager.login("admin", "pass"); new ThreadLocal<UserInfo>().set(new UserInfo("Wrong username", "Another thread?")); secureBean.writeSecureMessage(); securityManager.logout(); } } 

Application.java (works again)

 public class Application { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); SecureBean secureBean = (SecureBean) context.getBean("secureBean"); SecurityManager securityManager = new SecurityManager(); securityManager.login("admin", "pass"); secureBean.writeSecureMessage(); securityManager.logout(); } } 

    1 answer 1

    ThreadLocal Definition:

    This class provides stream local variables. These variables differ from their usual counterparts in that each thread that accesses it (via the get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that want to associate a state with a thread (for example, a user ID or transaction ID).

    From your code, you can see that you can call the writeSecureMessage() method if the username is admin .

    ThreadLocal is used here so that it cannot be done from another thread. That is, if you are creating a new stream, then again you need to do login("admin",) .