Firefox не поддерживает рисование SVG-изображений на холсте, если у svg-файла нет атрибутов width / height на корневом элементе , и эти атрибуты width / height не являются процентами. Это давняя ошибка .
Вам нужно будет отредактировать файл icon.svg, чтобы он соответствовал вышеуказанным критериям.
Прокси, сгенерированный для @Transactional
поведение, служит другой цели, чем ограниченные по объему прокси.
Эти @Transactional
прокси является тем, который обертывает определенный боб для добавления поведения управления сеансами. Все вызовы метода выполнят управление транзакциями прежде и после делегирования к фактическому бобу.
при иллюстрировании его это было бы похоже
main -> getCounter -> (cglib-proxy -> MyBeanB)
В наших целях, можно по существу проигнорировать его поведение (удалите @Transactional
, и необходимо видеть, что то же поведение, кроме Вас не будет иметь прокси cglib).
@Scope
прокси ведет себя по-другому. Состояния документации:
[...] необходимо ввести объект прокси, который представляет тот же открытый интерфейс как ограниченный по объему объект , но это может также получить реальный целевой объект от соответствующего объема (такого как Запрос HTTP) и вызовы метода делегата на реальный объект.
то, Что действительно делает Spring, создает одноэлементное бобовое определение для типа фабрики, представляющей прокси. Соответствующий объект прокси, однако, запрашивает контекст для фактического боба для каждого вызова.
при иллюстрировании его это было бы похоже
main -> getCounter -> (cglib-scoped-proxy -> context/bean-factory -> new MyBeanB)
, Так как MyBeanB
опытный боб, контекст будет всегда возвращать новый экземпляр.
В целях этого ответа, предположите, что Вы получили MyBeanB
непосредственно с [1 144]
MyBeanB beanB = context.getBean(MyBeanB.class);
, который является по существу, что Spring делает для удовлетворения @Autowired
инжекционная цель.
В Вашем первом примере,
@Service
@Scope(value = "prototype")
public class MyBeanB {
Вы объявляете опытный боб определение (через аннотации). @Scope
имеет proxyMode
элемент, который
Определяет, должен ли компонент быть настроен как ограниченный по объему прокси и если так, должен ли прокси быть основан на интерфейсе или основан на подклассе.
Значения по умолчанию к [1 117], который обычно указывает, что никакой ограниченный по объему прокси не должен быть создан , если другое значение по умолчанию не было настроено на уровне инструкции сканирования компонента.
, Таким образом, Spring не создает ограниченный по объему прокси для получающегося боба. Вы получаете тот боб с [1 150]
MyBeanB beanB = context.getBean(MyBeanB.class);
, у Вас теперь есть ссылка на новое MyBeanB
объект, созданный Spring. Это похоже на любой другой объект Java, вызовы метода перейдут непосредственно к экземпляру, на который ссылаются.
, Если бы Вы использовали getBean(MyBeanB.class)
снова, Spring возвратила бы новый экземпляр, так как бобовое определение для опытный боб . Вы не делаете этого, таким образом, все Ваши вызовы метода переходят к тому же объекту.
В Вашем втором примере,
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyBeanB {
Вы объявляете ограниченный по объему прокси, который реализован через cglib. При запросе боба этого типа от Spring с [1 154]
MyBeanB beanB = context.getBean(MyBeanB.class);
Spring знает, что MyBeanB
ограниченный по объему прокси и поэтому возвращает объект прокси, который удовлетворяет API [1 121] (т.е. реализует все его открытые методы), который внутренне знает, как получить фактический боб типа MyBeanB
для каждого вызова метода.
Попытка, работающая
System.out.println("singleton?: " + (context.getBean(MyBeanB.class) == context.getBean(MyBeanB.class)));
, Это возвратится true
вывод подсказок тому, что Spring возвращает одноэлементный объект прокси (не опытный боб).
На вызове метода, в реализации прокси, Spring будет использовать специальное предложение getBean
версия, которая знает, как различать определение прокси и фактическое MyBeanB
бобовое определение. Это возвратит новое MyBeanB
экземпляр (так как это - прототип), и Spring делегирует вызов метода к нему посредством отражения (классик Method.invoke
).
Вашим третьим примером является по существу то же как Ваша секунда.