Как эта операция называется JavaScript [duplicate]

Поле, аннотированное @Autowired, является null, потому что Spring не знает о копии MileageFeeCalculator, которую вы создали с помощью new, и не знал, чтобы ее автоустанавливать.

Контейнер Spring Inversion of Control (IoC) имеет три основных логических компонента: реестр (называемый ApplicationContext) компонентов (beans), доступных для использования приложением, система настройки, которая вводит объектов в них путем сопоставления зависимостей с компонентами в контексте и решателя зависимостей, которые могут смотреть на конфигурацию множества различных компонентов и определять, как создавать и настраивать их в необходимом порядке.

Контейнер IoC не является волшебным, и он не может знать о Java-объектах, если вы как-то не сообщаете об этом. Когда вы вызываете new, JVM создает экземпляр нового объекта и передает его прямо вам - он никогда не проходит процесс настройки. Есть три способа настроить ваши компоненты.

Я опубликовал весь этот код, используя Spring Boot для запуска, в проекте GitHub ; вы можете посмотреть полный рабочий проект для каждого подхода, чтобы увидеть все, что вам нужно, чтобы заставить его работать. Тег с параметром NullPointerException: nonworking

Ввод ваших bean-компонентов

Наиболее предпочтительным вариантом является позволить Spring autowire все ваши компоненты; это требует наименьшего количества кода и является наиболее удобным для обслуживания. Чтобы сделать работу по автоустановке, как вы хотели, также автоустанавливайте MileageFeeCalculator следующим образом:

@Controller
public class MileageFeeController {

    @Autowired
    private MileageFeeCalculator calc;

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}

Если вам нужно создать новый экземпляр объекта службы для разных запросов, вы все равно можете использовать используя области весеннего компонента .

Тег, который работает путем ввода объекта службы @MileageFeeCalculator: working-inject-bean

Использовать @Configurable

Если вам действительно нужны объекты, созданные с new, которые будут автообновлены, вы можете использовать аннотацию Spring @Configurable вместе с AspectJ компиляцией во время компиляции для ввода ваших объектов , Этот подход вставляет код в конструктор вашего объекта, который предупреждает Spring о том, что он создается, так что Spring может настроить новый экземпляр. Это требует некоторой конфигурации в вашей сборке (например, компиляции с ajc) и включения обработчиков конфигурации среды Spring (@EnableSpringConfigured с синтаксисом JavaConfig). Этот подход используется системой активных записей Roo, чтобы позволить экземплярам new ваших объектов получать необходимую информацию о сохранении.

@Service
@Configurable
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService;

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile());
    }
}

Тег, который работает с помощью @Configurable на объекте службы: working-configurable

Ручной поиск: не рекомендуется

Этот подход подходит только для взаимодействия с устаревшим кодом в особых ситуациях. Почти всегда предпочтительнее создавать одноэлементный класс адаптеров, который Spring может использовать для autowire, и устаревший код может вызывать, но можно напрямую спросить контекст приложения Spring для bean-компонента.

Для этого вам нужно класс, к которому Spring может ссылаться на объект ApplicationContext:

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;   
    }

    public static ApplicationContext getContext() {
        return context;
    }
}

Затем ваш устаревший код может вызывать getContext() и извлекать необходимые ему компоненты:

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
        return calc.mileageCharge(miles);
    }
}

Тег, который работает путем ручного поиска объекта службы в контексте Spring: working-manual-lookup

16
задан Crescent Fresh 4 March 2011 в 10:12
поделиться

4 ответа

Во-первых, var [a, b] = f() отлично работает в JavaScript 1.7 - попробуйте!

Во-вторых, вы можете сгладить синтаксис использования слегка с помощью with():

var array = [1,2];
with (assign(array, { var1: null, var2: null }))
{
   var1; // == 1
   var2; // == 2
}

Конечно, это не позволит вам изменять значения существующих переменных, поэтому IMHO это намного менее полезно, чем функция JavaScript 1.7. В коде я пишу now , я просто возвращаю объекты напрямую и ссылаюсь на их членов - я буду ждать, когда функции 1.7 станут более доступными.

23
ответ дан Peter Mortensen 21 August 2018 в 21:48
поделиться
  • 1
    На сегодняшний день var [a,b] = [1,2]; приводит к синтаксической ошибке в Chrome. – Marcin 6 April 2012 в 17:24
  • 2
    @Marcin: JavaScript 1.7 является языком Mozilla . – Shog9♦ 6 April 2012 в 18:25
  • 3
    Обратите внимание, что with может быть опасным, так как собственные документы Mozilla «Использование с не рекомендуется и запрещено в строгом режиме ECMAScript 5. Рекомендуемая альтернатива - назначить объект, свойства которого вы хотите получить во временную переменную. & Quot; – Michael Mior 10 April 2013 в 14:59
  • 4
    Будет доступен в ECMAScript 6 около середины 2015 года, см. ru.wikipedia.org/wiki/ECMAScript – pkopac 25 February 2015 в 15:26
  • 5
    with также запрещен в строгом режиме, который является действительно полезным режимом для ... – T.J. Crowder 20 April 2015 в 14:31

Вам не нужна переменная «_». Вы можете напрямую создавать глобальные переменные с помощью области окна:

window["foo"] = "bar";
alert(foo); // Gives "bar"

Вот еще несколько пунктов:

  • Я бы не назвал эту функцию «присваивать «потому что это слишком общий термин.
  • Чтобы более точно напоминать синтаксис JS 1.7, я бы заставил функцию принять назначение в качестве первого аргумента, а источник - вторым аргументом.
  • Использование литерала объекта для передачи целевых переменных классно, но его можно путать с JS 1.7 destructuring, где пункт назначения фактически является объектом, а не массивом. Я предпочитаю использовать список имен переменных с разделителями-запятыми в виде строки.

Вот что я придумал:

function destructure(dest, src) {  
    dest = dest.split(",");  

    for (var i = 0; i < src.length; i++) {  
        window[dest[i]] = src[i];  
    }  
}  

var arr = [42, 66];  

destructure("var1,var2", arr); 

alert(var1); // Gives 42
alert(var2); // Gives 66
4
ответ дан Ates Goral 21 August 2018 в 21:48
поделиться
  • 1
    Единственное, с чем я согласен, это то, что разрушение может быть лучшим именем. * источник, назначение - стиль unix. * Заполнение глобальной области не очень приятно. Это не приводит к композиционной способности. * Написание выходных переменных в виде строки утомительно и сложнее для вашего редактора. Как писать SQL. – Anders Rune Jensen 15 October 2008 в 19:31
  • 2
    @AndersRuneJensen Так как это подражает назначению, назначение должно быть почти наверняка слева. Таким образом, он выглядит как [var1, var2] = arr. И destructure - ужасное, непознаваемое имя. Я думаю, что assign лучше - в конце концов, это предполагается как универсальная функция полезности. Если нет, то, может быть, massAssign? – Marnen Laibow-Koser 27 June 2014 в 20:36

В стандартном JavaScript мы привыкли ко всем видам уродства, и эмуляция назначения деструктуризации с использованием промежуточной переменной не так уж плоха:

function divMod1(a, b) {
    return [ Math.floor(a / b), a % b ];
}

var _ = divMod1(11, 3);
var div = _[0];
var mod = _[1];
alert("(1) div=" + div + ", mod=" + mod );

Однако, я думаю, что следующий шаблон более итоматичен:

function divMod2(a, b, callback) {
    callback(Math.floor(a / b), a % b);
}

divMod2(11, 3, function(div, mod) {
    alert("(2) div=" + div + ", mod=" + mod );
});

Обратите внимание, что вместо того, чтобы возвращать два результата в виде массива, мы передаем их как аргументы функции обратного вызова.

(см. код, запущенный на http: // jsfiddle.net/vVQE3/)

0
ответ дан Eamonn O'Brien-Strain 21 August 2018 в 21:48
поделиться

Вот что я сделал в PHPstorm 10:

Файл -> Настройки -> Языки и amp; Рамки -> ...

... задают версию языка JavaScript, например. JavaScript 1.8.5 ...

-> нажмите Apply.

1
ответ дан Sam SB 21 August 2018 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: