Не могу понять как это вообще работает. Использую 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();
}
}
Определение ThreadLocal
:
Этот класс предоставляет локальные переменные потока. Эти переменные
отличаются от их обычных аналогов тем, что каждый поток, который
обращается к нему (посредством метода get
или set
), имеет свою
собственную, независимо инициализированную копию переменной.
Экземпляры ThreadLocal
обычно представляют собой частные статические
поля в классах, которые хотят связать состояние с потоком (например,
идентификатор пользователя или идентификатор транзакции).
По вашему коду видно, что вы можете вызывать метод writeSecureMessage()
если имя пользователя admin
.
ThreadLocal
здесь используется, чтобы нельзя это было делать из другого потока. То есть, если вы создаете новый поток, то вам опять надо делать login("admin",)
.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Написал класс где генерируются случайные числа (без повторения значений) и записываются в массив
Возможно ли изменить позицию фигуры в канвасе, без того, чтоб все очищать или поверх этой фигуры налаживать новую? Позиция самой фигуры заранее...
как парсить HTML который создается через JS JavaScript то есть динамическую страницу, JSOUP с этим не справился это то и ясно, хотел попробовать через...