Контекст
Я разрабатываю для своей компании программное обеспечение, которое классифицирует веб-сайты, содержащие фишинг и вредоносное ПО, благодаря множественному алгоритму извлечения.
После извлечения функций мы используем пул классификаторов эмпирического и машинного обучения. Мы выбираем среди них благодаря собственной избирательной функции.
код
В основном у нас есть классы классификаторов, которые реализуют контракт AnalysisFunction
.
public abstract class AnalysisFunction {
abstract public StatusType analyze(List<TokenEntity> tokens);
abstract public double getPhishingProbability(List<TokenEntity> tokens);
}
Наш пул классификатора содержится в «пуле», который реализует AnalysisFunction
.
public class PoolAnalysisFunction extends AnalysisFunction{
private final List<AnalysisFunction> candidates;
private final ChoiceFunction choice;
private static final Logger LOG = LogManager.getLogger(PoolAnalysisFunction.class);
public PoolAnalysisFunction(List<AnalysisFunction> candidates, ChoiceFunction choice) {
this.candidates = candidates;
this.choice = choice;
}
@Override
public StatusType analyze(List<TokenEntity> tokens) {
try {
return choice.chooseAmong(candidates, tokens).analyze(tokens);
} catch (ImpossibleChoiceException e){
LOG.fatal("Not enough analysis function.", e);
return StatusType.CLEAN;
}
}
@Override
public double getPhishingProbability(List<TokenEntity> tokens) {
try {
return choice.chooseAmong(candidates, tokens).getPhishingProbability(tokens);
} catch (ImpossibleChoiceException e){
LOG.fatal("Not enough analysis function.", e);
return 0;
}
}
}
Чтобы упростить развертывание и тестирование новой функции, мы хотим сделать наш пул полностью настраиваемым и создавать экземпляры каждой функции по ее имени. Для достижения этой цели у нас есть ключ в нашем файле свойств, похожий на analysis.pool.functions=com.vadesecure.analysis.empirical.Function1,com.vadesecure.analysis.machine.AutomaticClassifier1
.
Благодаря этому я хочу создать экземпляры своих функций. Моя проблема в том, что эти классификаторы зависят от разных вещей, таких как настраиваемый объект конфигурации и модель машинного обучения. Я хотел бы ввести те зависимости, которые уже привязаны к моему инжектору hk2.
import org.glassfish.hk2.api.Factory;
public class PoolFunctionFactory implements Factory<AnalysisFunction> {
private final PoolAnalysisParameters parameters;
private static final Logger LOG = LogManager.getLogger(PoolAnalysisFunction.class);
@Inject
public PoolFunctionFactory(PoolAnalysisParameters parameters) {
this.parameters = parameters;
}
@Override
public AnalysisFunction provide() {
try {
Class<?> choice = Class.forName(parameters.getChoiceFunctionFQDN());
ChoiceFunction choiceFunction = new PhishingPriorityChoiceFunction(); // default choice
if(choice.getSuperclass().isInstance(ChoiceFunction.class)){
choiceFunction = (ChoiceFunction) choice.newInstance();
}
List<AnalysisFunction> analysisFunctions = new LinkedList<>();
// I want to instantiate here
}
return new PoolAnalysisFunction(analysisFunctions, choiceFunction);
} catch (ClassNotFoundException|IllegalAccessException|InstantiationException e){
LOG.fatal(e, e);
}
return null;
}
@Override
public void dispose(AnalysisFunction analysisFunction) {
LOG.trace(String.format("%s end of life", analysisFunction));
}
}
На примере модельно-зависимого классификатора:
public class SVMF2AnalysisFunction extends AnalysisFunction {
private final SVMContainer modelContainer;
private double probability = 0.0;
private double threshold = 0.9;
@Inject // i build this model in a parallel thread
public SVMF2AnalysisFunction(SVMContainer modelContainer) {
this.modelContainer = modelContainer;
}
@Override
public StatusType analyze(List<TokenEntity> tokens) {
if (modelContainer.getModel() == null) {
return null;
}
probability = modelContainer.getModel().analyse(tokens.stream());
return probability >= threshold ? StatusType.PHISHING : StatusType.CLEAN;
}
@Override
public double getPhishingProbability(List<TokenEntity> tokens) {
return probability;
}
}
Как я могу добиться этих экземпляров.
Мой первый подход заключался в том, чтобы внедрить serviceLocator, но я не нашел документации для этого, и мой коллега сказал мне, что это нехорошо.
Он сказал, чтобы я задокументировал себя про прокси, но мне это не кажется хорошим, или, возможно, я что-то пропустил.
{}
для блоков кода или выбрать код и его CTRL + K или команду-K) - person   schedule 28.04.2017SVMF2AnalysisFunction
с@Inject
на рабочем конструкторе? - person   schedule 28.04.2017SVMContainer
вAnalysisFunction
и передать его в качестве аргументаnewInstance()
(при условии, что это всегда один и тот же тип аргумента). ИЛИ используйте какой-то компонент Prototype для ваших функций - person   schedule 28.04.2017