Потоки в Spring. Не могу разобраться с ThreadLocal

153
22 ноября 2018, 02:00

Не могу понять как это вообще работает. Использую ThreadLocal<>. Простой пример:

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(Работает)

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(Всё так же работает)

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(Опять же работает)

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

Определение ThreadLocal:

Этот класс предоставляет локальные переменные потока. Эти переменные отличаются от их обычных аналогов тем, что каждый поток, который обращается к нему (посредством метода get или set), имеет свою собственную, независимо инициализированную копию переменной. Экземпляры ThreadLocal обычно представляют собой частные статические поля в классах, которые хотят связать состояние с потоком (например, идентификатор пользователя или идентификатор транзакции).

По вашему коду видно, что вы можете вызывать метод writeSecureMessage() если имя пользователя admin.

ThreadLocal здесь используется, чтобы нельзя это было делать из другого потока. То есть, если вы создаете новый поток, то вам опять надо делать login("admin",).

READ ALSO
Random без повторений числа

Random без повторений числа

Написал класс где генерируются случайные числа (без повторения значений) и записываются в массив

201
Помогите отредактировать код JQuery

Помогите отредактировать код JQuery

В наличии есть два JS кодаПервый:

128
Изменить позицию canvas html5

Изменить позицию canvas html5

Возможно ли изменить позицию фигуры в канвасе, без того, чтоб все очищать или поверх этой фигуры налаживать новую? Позиция самой фигуры заранее...

157
Как парсить HTML который создается через JavaScript? [закрыт]

Как парсить HTML который создается через JavaScript? [закрыт]

как парсить HTML который создается через JS JavaScript то есть динамическую страницу, JSOUP с этим не справился это то и ясно, хотел попробовать через...

170